可以繼承的枚舉類


在實現lexer和parser的過程中,要定義token的類型。《編程語言實現模式》中使用的是java代碼,直接定義static int TEXT = 1;並且可以在lexer擴展的時候繼承到實際使用的lexer里面。但C++定義類的static成員時,必須在外面單獨的進行初始化,對這一點不是很爽,在C++11中,實現了enum class,

 先看看這個enum class能不能滿足要求,例如

enum class TokenType{
    _EOF,
    TEXT
};

TokenType a = TokenType::TEXT;

那么就可以方便地使用TokenType::TEXT指代類型,只有同是TokenType,才能進行比較。如果要進行擴展,如下

enum class ExprTokenType:public TokenType{
    NUMBER,
    OP
};

希望新的類型ExprTokenType在TokenType的基礎上,添加兩種類型,既然是class,繼承應該沒問題的吧?但編譯的時候就報錯了。只好放棄這種方式了。

后來想到下面的實現,

class TokenType{
public:
    TokenType(){
        nameMap = {"_EOF","TEXT"};    
    }
    string Name(int x){
        return nameMap.at(x);
    }
public:
    const static int _EOF = 0; // const static 成員 可以在這里直接初始化, 
                               // 如果只是const修飾,const成員需要在構造函數的初始化列表里面進行賦值
                               // public成員, 可以像 enum class類似地,使用TokenType.TEXT訪問 
    const static int TEXT = 1;
protected:
    vector<string> nameMap;// 可以根據 類型 得到其名稱,便於調試,
}TokenType;

class ExprTokenType:public TokenType{
public:
    ExprTokenType(){
        nameMap.push_back("NUMBER"); // 為新添加的類型添加對應的名稱, 
        nameMap.push_back("OP");    
    }
public:
    const static int NUMBER = 2;
    const static int OP = 3;
}ExprTokenType; 
// 這里定義一個同名的實例,以后就可以直接使用 類名.類型,
// 如果不這樣做的話,或許把它所有的內容都聲明為static,也是同樣的。

期望的功能都實現了,只是這與enum class不一樣,不是類型安全的。不過沒關系,能用就已經很好了。

下面是測試代碼,

int main(){
    cout << "---test enum type---" << endl;
    int a = TokenType::TEXT;
    cout << "TokenType a:" << a << endl;
    cout << "ToeknType a:" << TokenType.Name(a) << endl;
    int b = ExprTokenType::OP;
    cout << "ExprTokenType b:" << b << endl;
    cout << "ExprToeknType b:" << ExprTokenType.Name(b) << endl;
    b = ExprTokenType::TEXT;
    cout << "ExprTokenType b:" << b << endl;
    cout << "ExprToeknType b:" << ExprTokenType.Name(b) << endl;
    
    if(a==b)
        cout << "test done." << endl;
    return 0;
}

需要注意的是,編譯的時候需要添加C++11的支持,g++ -std=c++0x .....

應該有更好的形式來實現吧,希望能與大家交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM