簡體   English   中英

虛擬數據類型/枚舉

[英]virtual data type/enum

我想要一個這樣的虛擬課:

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設備,可用於請求和接收用戶輸入。 創建硬件類后,它將傳遞指向正確配置類的指針,因此在請求時顯示正確的提示。

第一:您需要一個抽象類。 (抽象類是至少具有一個純虛函數的虛擬基類是從其virtual派生的類。)

然后:不,您想要的是不可能的。 您不能向前聲明一個enum並在以后定義它,更不用說以其他方式定義它了。 即使您可以:如果有人將epid_HappyBirthday傳遞給不知道的Configuration2 ,會發生什么?

我建議你想做的事(而不是你認為你的方式是否找到如何做到這一點的作品),也許有人能拿出一個成語來解決你的問題給我們解釋一下。

只要您不希望保留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:
};

您不能將編譯時類型檢查與運行時虛擬函數解析混合使用。

你可以有通用的

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

我的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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM