我想要一个像这样的虚拟类:
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设备,可用于请求和接收用户输入。创建硬件类时,它将传递指向正确配置类的指针,因此在请求时显示正确的提示。
答案 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;