2

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

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

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

4

4 回答 4

4

您可能可以使用模板获得大部分您想要的东西......只要您不希望保留一个集合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:
};
于 2009-08-28T15:36:37.813 回答
3

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

然后:不,你想要的是不可能的。您不能前向声明一个enum并在以后定义它,更不用说以不同的方式定义它了。即使你可以:如果有人通过不知道它会发生epid_HappyBirthday什么Configuration2

我建议你向我们解释想做什么(而不是你认为你发现如何做到这一点的方式是否有效),也许有人可以想出一个成语来解决你的问题。

于 2009-08-28T11:15:34.797 回答
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.

于 2009-08-28T11:16:26.387 回答
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;
于 2009-08-28T11:44:59.840 回答