代码之家  ›  专栏  ›  技术社区  ›  Patrick

虚拟数据类型/枚举

  •  2
  • Patrick  · 技术社区  · 15 年前

    我想要一个这样的虚拟课堂:

    class Configuration 
    {
    public:
        enum EPromptId;
    
        virtual CString getPrompt( EPromptId promptId ) = 0;
    private:
    };
    

    这样每个派生配置都可以有自己的一组epromptid

     class Configuration1 : public Configuration
    {
    public:
        enum EPromptId{
            epid_HappyBirthday
        };
    
        CString getPrompt( EPromptId promptId ){
            return "";
        }
    private:
    };
    
    class Configuration2 : public Configuration
    {
    public:
        enum EPromptId{
            epid_JummpingJehoshaphat
        };
    
        CString getPrompt( EPromptId promptId ){
            return "";
        }
    private:
    };
    

    这将失败,因为每个类都需要实现一个带有configuration::epromptid参数的虚拟函数(而不是本代码中的configuration1::epromptid或configuration2::epromptid)。

    是否可以让基类识别参数类型,但在每个派生类中定义不同的值(可能不使用枚举,但保持它的强类型,即不使用int)。

    编辑:我想要两个不同的配置为两个不同的'应用程序'。提示可以保存在数据库表中,但每个“应用程序”都有自己的表。指向基本配置类的指针包含在一个类中,该类与某些硬件接口(即实际显示的硬件)。硬件是一个IO设备,可用于请求和接收用户输入。创建硬件类时,将向其传递指向正确配置类的指针,因此在请求时显示正确的提示。

    4 回复  |  直到 15 年前
        1
  •  3
  •   sbi    15 年前

    第一:你想要一个 摘要 班级。(抽象类是指至少有一个 纯虚拟 功能。一 虚拟基类 是一个 virtual 来源于。)

    然后:不,你想要的是不可能的。您不能转发声明 enum 以后再定义,更不用说用不同的定义了。即使你可以:如果有人经过会发生什么? epid_HappyBirthday Configuration2 谁不知道呢?

    我建议你向我们解释 什么 你想做(而不是 怎样 或许有人能想出一个成语来解决你的问题。

        2
  •  3
  •   Caleb Huitt - cjhuitt    15 年前

    你也许可以得到你想要的模板…只要你不想在 Configuration* 用那种方式接近他们(你没有,是吗?因为你需要知道他们的类型才能知道该通过什么……)

    template< typename ENUM_TYPE >
    class Configuration 
    {
    public:
        virtual CString getPrompt( ENUM_TYPE promptId ) = 0;
    private:
    };
    

    然后

    enum EPromptId{
        epid_HappyBirthday
    };
    
    class Configuration1 : public Configuration< EPromptId >
    {
    public:
        CString getPrompt( EPromptId promptId ){
            return "";
        }
    private:
    };
    
        3
  •  1
  •   pingw33n    15 年前

    不能将编译时类型检查与运行时虚拟函数解析混合使用。

    你可以用普通的

    class Configuration 
    {
    public:
        virtual CString getPrompt( int promptId ) = 0;
    private:
    };
    

    在导数中定义两个成员函数:

    class Configuration1 : public Configuration
    {
    public:
        enum EPromptId{
            epid_HappyBirthday
        };
    
        CString getConfiguration1Prompt( EPromptId promptId ){
            return "";
        }
        virtual CString getPrompt( int promptId )
        {
          return getConfiguration1Prompt(static_cast<EPromptId>(promptId));
        } 
    private:
    };
    
    class Configuration2 : public Configuration
    {
    public:
        enum EPromptId{
            epid_JummpingJehoshaphat
        };
    
        CString getConfiguration2Prompt( EPromptId promptId ){
            return "";
        }
        virtual CString getPrompt( int promptId )
        {
          return getConfiguration2Prompt(static_cast<EPromptId>(promptId));
        } 
    private:
    };
    

    如果你想确保有效 promptId 您应该在运行时在子类中手动检查它。

    无论如何,这种方法是没有用的,因为使用泛型 getPrompt() 函数需要知道使用哪个子类才能访问其 EPromptId .

        4
  •  0
  •   adrianm    15 年前

    我的C++有点生疏了,但是你不能做点什么吗?

    struct EPromptId {
        EPromptId() mId(sId++) { }
        operator int() { return mId; }
        friend static bool operator==(EPromptId lhs, EPromptId rhs) { 
            return lhs.mId == rhs.mId;
        }
    private:
        int mId;
        static int sId;
    };
    
    struct configuration1 {
        static const EPromptId epid_HappyBirthday;
        static const EPromptId epid_xxx;
    
        CString getPrompt(EPromptId promptId ){
            if (promptId == epid_HappyBirthday)
                return "";
            else if (promptId == epid_xxx)
        }
    }
    
    // somewhere else
    EPromptId configuration1::epid_HappyBirthday;
    EPromptId configuration1::epid_xxx;
    

    如果要手动控制每个id,只需添加一个和int构造函数
    epromptid(int id)中间(id){}

    并将初始化更改为

    EPromptId configuration1::epid_HappyBirthday = 1;
    EPromptId configuration1::epid_xxx = 5;