1

ビルダー デザイン パターンを使用することにしたメッセージ クラスがあります。各メッセージは、完全に構築されると、非常によく似たものになります。情報を保持するために a を使用しstd::stringます (実際には独立した文字なので、使用することもできvector<char>ましたが、.c_str()便利でした。

メッセージの各サブタイプの構築方法は同じです (ビルド ヘッダー、ビルド カーゴ、ビルド フッター、計算チェックサム...これはMessageBuilderクラスで定義されます (そして、カスタム メッセージ ビルダー クラスに継承されます)。

class MessageBuilder
{
public:
    // implementation details for all messages
    static const int32 MsgDelimeter = 99;
    // ...       

    Message getMsg();

    void buildMessage();

protected:
    MessageBuilder(uint8 msgID, uint8 cargoLen, uint8 csi, const uint8* cargo, const uint8 length)
        : m_msgID(msgID), m_cargoLen(cargoLen), m_csi(csi),
        m_cargo(cargo), m_contents(""), m_msg(m_contents) 
    { }

    // I previously tried passing cargo and length as just a std::string
    // if I could get that to work it would also be fine

    void buildHeader();
    void buildCargo();
    void buildFooter();
    void resizeContents();
    void calculateCheckSum();

    // message is built in m_contents
    Message::string m_contents;
    Message::string m_cargo;
    Message m_msg;

    // variables specific to msg type
    uint8 m_msgID;
    uint8 m_cargoLen;
    uint8 m_csi;

private:
};

次に、特定のメッセージを作成するために、特定のクラスがあります。

class CustomMessageABuilder : public MessageBuilder
{
public:
    static const uint8 CustomMessageAID = 187;
    // more details
    // ...

    // what I want to do
    // static const uint8 CustomMessageACargo[4] = {0x65, 0xc7, 0xb4, 0x45};        

    // ** HERE ** 
    CustomMessageABuilder () 
        : MessageBuilder(CustomMessageAID, 
            CustomMessage1CargoLen, 
            //...
            CustomMessageACargo,
            CustomMessageALength
             {  }


};

とにかく、私がやりたいのは、唯一のカスタム文字列であるカーゴをCustomMessageABuilderコンストラクターからMessageBuilderクラスに渡し、メッセージの途中に格納することです。

カーゴはメッセージごとに異なりますが、同じ方法で保存されるため、カーゴを保存/作成するためのすべてのロジックは基本MessageBuilderクラスにあります。msgID、cargoLen、cargo などのすべての違いは、CustomMessageBuilderクラスの定数です。

これにより、メッセージ クラスを非常にシンプルに保つことができます。

class Message
{
public:
    typedef std::string string;
    // ctor
    Message(string);
    // dtor
    ~Message();
    // copy ctor
    Message(const Message&);
    // assignment operator
    Message& operator=(const Message&);

    // getters
    uint8 getLength() const;
    const string& getData() const;
    const uint8* getCSTR() const;
    // setters
    void setData(const string&);

protected:
    // ctor
    Message() : m_contents("") { }

    // contents of entire message
    string m_contents;

};

だから私はそれがすべてこれに要約すると思います:

クラスの文字/16進値(各メッセージカーゴ)の定数配列を定義する最良の方法は何ですか?(それでもコンストラクタの初期化リストに渡すことができます)? または、私が見逃しているこれを行う明白な方法を教えてください。

注: 他のメッセージ クラスの場合、カーゴは動的コンテンツになりますが、常に固定長です。

注 2: 最終的には、 を所有してCustomMessageBuilder()に伝えるディレクター クラスを作成しbuildMessage()ます。

ヘルプ、アドバイス、批判などは大歓迎です。

4

1 に答える 1

1

静的constメンバーは、クラスの外部で初期化できます。

#include <iostream>

class A
{
public:
     static const char cargo[4];
};

const char A::cargo[4] = {0x65, 0xc7, 0xb4, 0x45};

int main()
{
    std::cout << A::cargo[0] << A::cargo[1] << A::cargo[2] << A::cargo[3] << std::endl;
}
于 2013-02-02T06:12:11.147 に答える