虚拟数据类型/枚举

时间:2009-08-28 10:55:46

标签: c++ virtual

我想要一个像这样的虚拟类:

class Configuration 
{
public:
    enum EPromptId;

    virtual CString getPrompt( EPromptId promptId ) = 0;
private:
};

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

 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)。

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

4 个答案:

答案 0 :(得分:3)

首先:你想要一个抽象类。 (抽象类是至少有一个纯虚拟函数的类。虚拟基类是一个派生自virtual的类。)

然后:不,你想要的是不可能的。您不能转发声明enum并在以后定义它,更不用说以不同方式定义它。即使你可以:如果有人将epid_HappyBirthday传递给不知道它的Configuration2,会发生什么?

我建议你向我们解释你想要做什么<(而不是你认为你发现 这样做的方式),也许有人可以上来用成语来解决你的问题。

答案 1 :(得分:3)

您可以通过模板获得大部分内容...只要您不希望保留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:
};

答案 2 :(得分:1)

您不能将编译时类型检查与运行时虚函数解析混合在一起。

您可以使用通用

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

答案 3 :(得分:0)

我的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)mId(id){}

并将初始化更改为

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