7

少し前に書いたアプリケーションを Java から C++ に移植しています。私がすぐに気づいたことの 1 つは、Java の豊富な Enum (Java 5 で導入されたもの) が、C++ で提供されるものよりもはるかに優れているということでした。C++0x、およびそれ以降の C++11 の「厳密に型指定された列挙型」(別名列挙型クラス) は、Java 列挙型が提供する豊富な機能をまだ提供しておらず、ここでこの機能をエミュレートするものを見つけることができませんでした。

私は、いくつかの機能をクラスに沿ったものとしてエミュレートしようと試みました。これを実装するための助けが必要です。おそらく、適切であればテンプレートを使用します (これを実装するには、より一般的な方法が必要なようです)。文字列名を介して特定の Enum を検索する機能がかなり冗長に実装されていることがわかります (これは Java ENUM のvalueOf(String str)メソッドのエミュレーションです - 動作します - しかし最適とはほど遠いと確信しています) . Enum インスタンスを実装した方法は、クラス内の static const インスタンスを使用しています - これは Stack Overflow のどこかで見つけました - しかし、正確な場所を思い出すことはできません - 申し訳ありません。

参考までに、このアプリケーションは NMEA 文字列パーサーです。さらに興味深い Enum クラスをいくつか紹介します。

ここにヘッダーがあります

#ifndef _NMEASentence_h_
#define _NMEASentence_h_

// SYSTEM INCLUDES
#include <stdint.h>
#include <string>

// APPLICATION INCLUDES
// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

 /**
 *  Name:  NMEASentence
 */
class NMEASentence
{
public:
    static const int MAX_LEN;
    static const char START;
    static const char CKSM_DELIM;
    static const char CR;
    static const char LF;

    NMEASentence(
        const std::string rPrefix,
        const std::string& rParams)
        : mPrefix(rPrefix)
        , mParams(rParams)
    {};

    // make the class abstract
    virtual ~NMEASentence() = 0;

protected:
    std::string mPrefix;
    std::string mParams;
};

#endif // _NMEASentence_h_

CPPはこちら

// SYSTEM INCLUDES
// APPLICATION INCLUDES
#include "vcdu/NMEASentence.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
const int NMEASentence::MAX_LEN = 82;
const char NMEASentence::START = '$';
const char NMEASentence::CKSM_DELIM = '*';
const char CR = '\r';
const char LF = '\n';    

// implementation of the pure virtual dtor allowed
// its a trick to allow class to be abstract
NMEASentence::~NMEASentence()
{};

これは、ジェネリック NMEASentence クラスのサブクラスです。

#ifndef _CDUMessage_h_
#define _CDUMessage_h_

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "vcdu/NMEASentence.h"
#include "vcdu/CDUEnumConstants.h"

// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

/**
 * CDUMessage
 */
class CDUMessage : public NMEASentence
{
public:
    /**
     * 5 classifications of message types, The type specifies the
     * number and type of each parameter
     */
    typedef enum CDUMessageSubType {
        Alive,
        Display,
        XYDisplay,
        Status,
        Keyboard,
        Configuration
    } CDUMessageSubType;

    /**
     * enumeration of the supported message types & their arg count
     */
    static class CDUMessageType {
    public:
        static const CDUMessageType CDUAlive;
        // the following 3 messages are associated with the title line
        static const CDUMessageType CDUDisplayDataStatusBlock;
        static const CDUMessageType CDUDisplayTitle;
        static const CDUMessageType CDUDisplayPageNumber;
        // these messages are associated with the active display area
        static const CDUMessageType CDUDisplayScratchPad;
        static const CDUMessageType CDUDisplayLS1Text;
        static const CDUMessageType CDUDisplayLS2Text;
        static const CDUMessageType CDUDisplayLS3Text;
        static const CDUMessageType CDUDisplayLS4Text;
        static const CDUMessageType CDUDisplayLS5Text;
        static const CDUMessageType CDUDisplayLS6Text;
        static const CDUMessageType CDUDisplayLS1SText;
        static const CDUMessageType CDUDisplayLS2SText;
        static const CDUMessageType CDUDisplayLS3SText;
        static const CDUMessageType CDUDisplayLS4SText;
        static const CDUMessageType CDUDisplayLS5SText;
        static const CDUMessageType CDUDisplayLS6SText;
        static const CDUMessageType CDUDisplayRS1Text;
        static const CDUMessageType CDUDisplayRS2Text;
        static const CDUMessageType CDUDisplayRS3Text;
        static const CDUMessageType CDUDisplayRS4Text;
        static const CDUMessageType CDUDisplayRS5Text;
        static const CDUMessageType CDUDisplayRS6Text;
        static const CDUMessageType CDUDisplayRS1SText;
        static const CDUMessageType CDUDisplayRS2SText;
        static const CDUMessageType CDUDisplayRS3SText;
        static const CDUMessageType CDUDisplayRS4SText;
        static const CDUMessageType CDUDisplayRS5SText;
        static const CDUMessageType CDUDisplayRS6SText;
        // this is a special message to clear the screen buffer
        static const CDUMessageType CDUDisplayCLS;
        static const CDUMessageType CDUDisplayPutString;
        static const CDUMessageType CDUStatus;
        static const CDUMessageType CDUKeyboard;
        static const CDUMessageType CDUSet;
        static const CDUMessageType CDUGet;

        inline std::string getPrefix() const {
            return mPrefix;
        }

        inline CDUMessageSubType getMesageSubType() const {
            return mSubType;
        }

        inline virtual int getTextRowIndex() const {
            return mTextRowIndex;
        }

        inline JustifyStyle getJustifyStyle() const {
            return mJustifyStyle;
        }

        static std::vector<CDUMessageType>& getValues() {
            static std::vector<CDUMessageType> gValues;
            if (gValues.empty()) {
                gValues.push_back(CDUAlive);
                gValues.push_back(CDUDisplayDataStatusBlock);
                gValues.push_back(CDUDisplayTitle);
                gValues.push_back(CDUDisplayPageNumber);
                gValues.push_back(CDUDisplayScratchPad);
                gValues.push_back(CDUDisplayLS1Text);
                gValues.push_back(CDUDisplayLS2Text);
                gValues.push_back(CDUDisplayLS3Text);
                gValues.push_back(CDUDisplayLS4Text);
                gValues.push_back(CDUDisplayLS5Text);
                gValues.push_back(CDUDisplayLS6Text);
                gValues.push_back(CDUDisplayLS1SText);
                gValues.push_back(CDUDisplayLS2SText);
                gValues.push_back(CDUDisplayLS3SText);
                gValues.push_back(CDUDisplayLS4SText);
                gValues.push_back(CDUDisplayLS5SText);
                gValues.push_back(CDUDisplayLS6SText);
                gValues.push_back(CDUDisplayRS1Text);
                gValues.push_back(CDUDisplayRS2Text);
                gValues.push_back(CDUDisplayRS3Text);
                gValues.push_back(CDUDisplayRS4Text);
                gValues.push_back(CDUDisplayRS5Text);
                gValues.push_back(CDUDisplayRS6Text);
                gValues.push_back(CDUDisplayRS1SText);
                gValues.push_back(CDUDisplayRS2SText);
                gValues.push_back(CDUDisplayRS3SText);
                gValues.push_back(CDUDisplayRS4SText);
                gValues.push_back(CDUDisplayRS5SText);
                gValues.push_back(CDUDisplayRS6SText);
                gValues.push_back(CDUDisplayCLS);
                gValues.push_back(CDUDisplayPutString);
                gValues.push_back(CDUStatus);
                gValues.push_back(CDUKeyboard);
                gValues.push_back(CDUSet);
                gValues.push_back(CDUGet);
            }
            return gValues;
        }
    private:
        CDUMessageType(const std::string& rPrefix,
            const CDUMessageSubType& rSubType,
            const JustifyStyle& rJustifyStyle,
            const int& rTextRowIndex)
            : mPrefix (rPrefix)
            , mSubType (rSubType)
            , mJustifyStyle(rJustifyStyle)
            , mTextRowIndex(rTextRowIndex)
        {}

        std::string mPrefix;
        CDUMessageSubType mSubType;
        JustifyStyle mJustifyStyle;
        int mTextRowIndex;
    };

    CDUMessageType getMessageType() const {
        return mMessageType;
    };

    virtual ~CDUMessage(){};
protected:
    /**
     * Alternative Simplified Constructor
     * @param aMessageType
     * @param aParams
     */
    CDUMessage(const CDUMessageType& rMessageType, const std::string& rParams)
        : NMEASentence (rMessageType.getPrefix(), rParams)
        , mMessageType (rMessageType)
    {};

    CDUMessageType mMessageType;
};

#endif // _CDUMessage_h_

そして対応するCPP

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "vcdu/CDUMessage.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// this is the heartbeat message (not associated with any line => -1 for last paramter)
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUAlive ("PCDUALIVE", CDUMessage::Alive, JustifyStyle::Left, -1);

// the following 3 messages are associated with the title line
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayDataStatusBlock("PCDUDSB", CDUMessage::Display,  JustifyStyle::Left, 0);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayTitle("PCDUTIT", CDUMessage::Display, JustifyStyle::Center, 0);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPageNumber("PCDUPGE", CDUMessage::Display, JustifyStyle::Right, 0);

// these messages are associated with the active display area
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayScratchPad("PCDUSPD", CDUMessage::Display,  JustifyStyle::Left, 13);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1Text("PCDUL1T", CDUMessage::Display,  JustifyStyle::Left, 2);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2Text("PCDUL2T", CDUMessage::Display,  JustifyStyle::Left, 4);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3Text("PCDUL3T", CDUMessage::Display,  JustifyStyle::Left, 6);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4Text("PCDUL4T", CDUMessage::Display,  JustifyStyle::Left, 8);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5Text("PCDUL5T", CDUMessage::Display,  JustifyStyle::Left, 10);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6Text("PCDUL6T", CDUMessage::Display,  JustifyStyle::Left, 12);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1SText("PCDUL1S", CDUMessage::Display,  JustifyStyle::Left, 1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2SText("PCDUL2S", CDUMessage::Display,  JustifyStyle::Left, 3);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3SText("PCDUL3S", CDUMessage::Display,  JustifyStyle::Left, 5);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4SText("PCDUL4S", CDUMessage::Display,  JustifyStyle::Left, 7);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5SText("PCDUL5S", CDUMessage::Display,  JustifyStyle::Left, 9);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6SText("PCDUL6S", CDUMessage::Display,  JustifyStyle::Left, 11);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1Text("PCDUR1T", CDUMessage::Display, JustifyStyle::Right, 2);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2Text("PCDUR2T", CDUMessage::Display, JustifyStyle::Right, 4);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3Text("PCDUR3T", CDUMessage::Display, JustifyStyle::Right, 6);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4Text("PCDUR4T", CDUMessage::Display, JustifyStyle::Right, 8);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5Text("PCDUR5T", CDUMessage::Display, JustifyStyle::Right, 10);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6Text("PCDUR6T", CDUMessage::Display, JustifyStyle::Right, 12);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1SText("PCDUR1S", CDUMessage::Display, JustifyStyle::Right, 1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2SText("PCDUR2S", CDUMessage::Display, JustifyStyle::Right, 3);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3SText("PCDUR3S", CDUMessage::Display, JustifyStyle::Right, 5);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4SText("PCDUR4S", CDUMessage::Display, JustifyStyle::Right, 7);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5SText("PCDUR5S", CDUMessage::Display, JustifyStyle::Right, 9);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6SText("PCDUR6S", CDUMessage::Display, JustifyStyle::Right, 11);

// these messages are not associated with a paricular line# which is why we specify -1 for the last parameter
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayCLS("PCDUCLS", CDUMessage::Display,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPutString("PCDUPUTS", CDUMessage::XYDisplay,  JustifyStyle::None, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUStatus("PCDUSID", CDUMessage::Status,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUKeyboard("PCDUKEY", CDUMessage::Keyboard,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUSet("PCDUSETV", CDUMessage::Configuration,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUGet("PCDUGETV", CDUMessage::Configuration, JustifyStyle::Left, -1);

Enum がどのように使用されるかの一般的なパターンをここで示すために、アプリケーション全体で使用する必要のある他の Enum C++ クラスをいくつか示します。それらはすべて非常によく似ており、これを実装するためのより簡単で冗長な方法があるに違いないと感じずにはいられません。どんな助けやアイデアも大歓迎です。

class JustifyStyle {
public:
    static const JustifyStyle Left, Center, Right, None;
    inline std::string getName() const {
        return mName;
    }
private:
    JustifyStyle(const std::string& rName) 
        : mName(rName)
    {}
    std::string mName;
};

class FontSize {
public:
    static const FontSize F1, F2, F3, F4, F5, F6;
    inline std::string getName() const {
        return mName;
    }
    static std::vector<FontSize>& getValues() {
        static std::vector<FontSize> gValues;
        if (gValues.empty()) {
            gValues.push_back(F1);
            gValues.push_back(F2);
            gValues.push_back(F3);
            gValues.push_back(F4);
            gValues.push_back(F5);
            gValues.push_back(F6);
        }
        return gValues;
    }
private:
    FontSize(const std::string& rName) 
        : mName(rName)
    {}
    std::string mName;
};

class FontStyle {
public:
    static const FontStyle S, B, I, U, N;
    inline std::string getName() const {
        return mName;
    }
    static std::vector<FontStyle>& getValues() {
        static std::vector<FontStyle> gValues;
        if (gValues.empty()) {
            gValues.push_back(S);
            gValues.push_back(B);
            gValues.push_back(I);
            gValues.push_back(U);
            gValues.push_back(N);
        }
        return gValues;
    }
    inline bool operator<(const FontStyle& rhs) const {
        return mName < rhs.mName;
    }
private:
    FontStyle(const std::string& rName) 
        : mName(rName)
    {}
    std::string mName;
};

class FontColor {
public:
    static const FontColor BLACK, CYAN, RED, YELLOW, GREEN, MAGENTA, AMBER, WHITE;
    inline int getValue() const {
        return mValue;
    }
    inline std::string getValueStr() const {
        return UtlStringUtils::integerToString(mValue);
    }
    static std::vector<FontColor>& getValues() {
        static std::vector<FontColor> gValues;
        if (gValues.empty()) {
            gValues.push_back(BLACK);
            gValues.push_back(CYAN);
            gValues.push_back(RED);
            gValues.push_back(YELLOW);
            gValues.push_back(GREEN);
            gValues.push_back(MAGENTA);
            gValues.push_back(AMBER);
            gValues.push_back(WHITE);
        }
        return gValues;
    }
private:
    // constructor
    FontColor(const int& rValue) 
        : mValue(rValue)
    {}
    int mValue;
};

class CDUFontChar {
public:
    // constructor
    CDUFontChar (
        const char cduChar = '\0',
        const FontSize& rSize = FontSize::F3,
        const std::set<FontStyle>& rStyles = std::set<FontStyle>(),
        const FontColor& rColor = FontColor::WHITE) 
        : mCDUChar (cduChar)
        , mSize (rSize)
        , mFontStyles(rStyles)
        , mColor(rColor)
    {}

    inline char getCDUChar() const {
        return mCDUChar;
    }

    inline FontSize getSize() const {
        return mSize;
    }

    inline std::set<FontStyle> getStyles() const {
        return mFontStyles;
    }

    inline FontColor getColor() const {
        return mColor;
    }
private:
    char mCDUChar;
    FontSize mSize;
    std::set<FontStyle> mFontStyles;
    FontColor mColor;
};
4

2 に答える 2

5

基本的に、Javaenumは、定数の優れたプラクティスと、シングルトンの不適切なプラクティスまたはアンチパターンとの間の橋渡しを目的とした言語機能です。C++ はenum整数定数を退屈なものにし、Java はそれらを完全なオブジェクト指向のシングルトンにしますが、開発者がそのconst-root を念頭に置いてくれることを願っています。そうです、あなたは正確に正しいです - 移植する方法は、C++ グローバル定数を使用することです。厳密に言えば、Java enum は定数である必要はありません。たとえば、非 final フィールドを持つことができますが、私はこれを悪い習慣と見なします (そして「これはそうである」と考えています)。同様に、C++ enum のすべてのメソッドは意味的にconst.

于 2012-09-04T19:13:25.637 に答える
4

スタック オーバーフローの問題を提起して以来、C++ で列挙型のような Java をシミュレートするために使用してきたアプローチを改良する機会がありました。以下に示すコード (ヘッダーと実装の cpp ファイル内) と、switch ステートメントで列挙型を使用する方法を示すコードのスニペットは、コード全体で最終的に使用したものです。微妙な点は、整数キャスト演算子の使用にあります (この場合、次のように使用される Value カスタム演算子の使用によるものです。

// integral operator cast for switch statements (cast to named enum)
inline operator const Value() const {
    return mValue;
}

ヘッダー ファイルCDUEnumConstants.h 内:

#ifndef _cduEnumConstants_h_
#define _cduEnumConstants_h_

// SYSTEM INCLUDES
#include <set>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

// APPLICATION INCLUDES
#include "util/UtlExceptions.h"
#include "util/UtlStringUtils.h"

// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
class Annunciator {
public:
    enum Value {
        // these are all undefined in the discrete sense
        undefined=-1, power=-2, fail=-3,
        // these are discrete bits
        exec=(1<<6), dspy=(1<<7), msg=(1<<8), ofst=(1<<9)
    };
    static const Annunciator AnnunciatorUNDEFINED;
    static const Annunciator AnnunciatorPOWER;
    static const Annunciator AnnunciatorFAIL;
    static const Annunciator AnnunciatorEXEC;
    static const Annunciator AnnunciatorDSPY;
    static const Annunciator AnnunciatorMSG;
    static const Annunciator AnnunciatorOFST;
    // used to store in a set
    inline bool operator<(const Annunciator& rhs) const {
        return mValue < rhs.mValue;
    }
    // used for comparisons
    inline bool operator==(const Annunciator& rhs) const {
        return mValue == rhs.mValue;
    }
    inline bool supported() const {
        return mValue > 0;
    }
    // integral operator cast for switch statements (cast to named enum)
    inline operator const Value() const {
        return mValue;
    }

    inline std::string getStringVal() const {
        return mStringVal;
    }

    static const std::set<Annunciator>& getValues() {
        static std::set<Annunciator> gValues;
        if (gValues.empty()) {
            gValues.insert(AnnunciatorUNDEFINED);
            gValues.insert(AnnunciatorPOWER);
            gValues.insert(AnnunciatorFAIL);
            gValues.insert(AnnunciatorEXEC);
            gValues.insert(AnnunciatorDSPY);
            gValues.insert(AnnunciatorMSG);
            gValues.insert(AnnunciatorOFST);
        }
        return gValues;
    }
    static Annunciator valueOf(const std::string& rStringVal) {
        for (const auto& next : getValues()) {
            if (next.getStringVal() == rStringVal) {
                return next;
            }
        }
        throw new UtlIllegalArgumentException(
            "Illegal Argument: " + rStringVal);
    }
private:
    Annunciator(const Value& rValue, const std::string& rStringVal)
        : mValue(rValue)
        , mStringVal(rStringVal)
    {}
    Value mValue;
    std::string mStringVal;
};


// FORWARD DECLARATIONS

// Extendable in the future
class CDUVariable {
public:
    enum Value {
        baud, firmware, type, serial
    };
    static const CDUVariable Baud, Firmware, Type, Serial;
    // used to store in a set
    inline bool operator<(const CDUVariable& rhs) const {
        return mValue < rhs.mValue;
    }
    // used for comparisons
    inline bool operator==(const CDUVariable& rhs) const {
        return mValue == rhs.mValue;
    }
    // integral operator cast for switch statements (cast to named enum)
    inline operator const Value() const {
        return mValue;
    }
    inline std::string getStringVal() const {
        return mStringVal;
    }
    static const std::set<CDUVariable>& getValues() {
        static std::set<CDUVariable> gValues;
        if (gValues.empty()) {
            gValues.insert(Baud);
            gValues.insert(Firmware);
            gValues.insert(Type);
            gValues.insert(Serial);
        }
        return gValues;
    }
    static CDUVariable valueOf(const std::string& rStringVal) {
        for (const auto& next : getValues()) {
            if (next.getStringVal() == rStringVal) {
                return next;
            }
        }
        throw new UtlIllegalArgumentException(
            "Illegal Argument: " + rStringVal);
    }
private:
    CDUVariable(const Value& rValue, const std::string& rStringVal)
        : mValue(rValue)
        , mStringVal(rStringVal)
    {}
    Value mValue;
    std::string mStringVal;
};

#endif // _cduEnumConstants_h_

および実装CDUEnumConstants.cppファイルでは、列挙型の初期値が初期化されます。

const Annunciator Annunciator::AnnunciatorUNDEFINED(Annunciator::undefined, "UNDEFINED");
const Annunciator Annunciator::AnnunciatorPOWER(Annunciator::power, "POWER");
const Annunciator Annunciator::AnnunciatorFAIL(Annunciator::fail, "FAIL");
const Annunciator Annunciator::AnnunciatorEXEC(Annunciator::exec, "EXEC");
const Annunciator Annunciator::AnnunciatorDSPY(Annunciator::dspy, "DSPY");
const Annunciator Annunciator::AnnunciatorMSG(Annunciator::msg, "MSG");
const Annunciator Annunciator::AnnunciatorOFST(Annunciator::ofst, "OFST");

const CDUVariable CDUVariable::Baud(CDUVariable::baud, "0");
const CDUVariable CDUVariable::Firmware(CDUVariable::firmware, "1");
const CDUVariable CDUVariable::Type(CDUVariable::type, "2");
const CDUVariable CDUVariable::Serial(CDUVariable::serial, "3");

ここで、ユーザー コードの switch ステートメントでCDUVariable列挙型を使用するには (他のメソッドの詳細は無視してください)、次を使用します。

std::unique_ptr<EngravityMessage>
VCDUManager::getConfigValue(
    const CDU_ID& rCduID,
    const std::unique_ptr<EngravityMessage>& rVarNameMessage)
{
    EngravityConfigMessage* pVariableName =
        static_cast<EngravityConfigMessage*>(rVarNameMessage.get());
    gpLogManager->add(FAC_PROCESS, PRI_NOTICE,
        "CDU_%d: getConfigValue\n", rCduID);
    CDUVariable variable = pVariableName->getCDUVariable();
    std::unique_ptr<EngravityMessage> variableValue;
    switch (variable) {
    case CDUVariable::baud:
        variableValue = std::unique_ptr<EngravityMessage>(
            new EngravityConfigMessage (
                EngravityMessageType::SetV, variable, "38400"));
        break;
    case CDUVariable::firmware:
        variableValue = std::unique_ptr<EngravityMessage>(
            new EngravityConfigMessage (
                EngravityMessageType::SetV, variable, "1.04"));
        break;
    case CDUVariable::type:
        variableValue = std::unique_ptr<EngravityMessage>(
            new EngravityConfigMessage (
                EngravityMessageType::SetV, variable, "737-NG"));
        break;
    case CDUVariable::serial:
        variableValue = std::unique_ptr<EngravityMessage>(
            new EngravityConfigMessage (
                EngravityMessageType::SetV, variable, "0074"));
        break;
    default:
        break;
    }
    return variableValue;
}

2 つの理由から Enum の 2 つの例を提供しました。1 つ目は、ソートされたセットを使用するように最適化された文字列から Enum 値を検索する方法を示したかったことです。2 つ目は、ここのパターンはテンプレート プログラミングを示唆しているように見えますが、テンプレートとして実装する機会がありませんでした-実際に実装できるかどうかはわかりません。

于 2013-11-15T16:09:03.743 に答える