4

私は2つの実装されたクラスを持っています:

class DCCmd :
    public DCMessage

class DCReply :
    public DCMessage

どちらも、双方向で送受信されるプロトコルメッセージです。

プロトコルの実装では、メッセージキューを作成する必要がありますが、DCMessage抽象的であるため、次のようなことはできません。

class DCMsgQueue{
private:
    vector<DCMessage> queue;
public:
    DCMsgQueue(void);
    ~DCMsgQueue(void);

    bool isEmpty();
    void add(DCMessage &msg);
    bool deleteById(unsigned short seqNum);
    bool getById(unsigned short seqNum, DCMessage &msg);
};

問題は、コンパイラが言うように、純粋な抽象メソッドを持っているため、「DCMessageをインスタンス化できない」ということです。

virtual BYTE *getParams()=0;

を削除し=0て空の中括弧を入れるとDCMessage.cpp問題は解決しますが、これは単なるハックです。

もう1つの解決策は、2つのDCMsgQueues:DCCmdQueueとを作成する必要があることDCReplyQueueですが、これは些細なことのために複製されたコードです。何か案は?=)

4

5 に答える 5

14

あなたが言ったようにそれは抽象的であるため、オブジェクトをインスタンス化することはできません。ただし、機能するDCMessageクラスへのポインタのベクトルを保持することはできます。リストにプッシュするときに、オブジェクトではなくメモリアドレスを追加する必要があります。

vector<DCMessage*> queue;

DCCmd* commandObject = new DCCmd(...params...);
queue.push_back(commandObject);

BYTE* params = queue[0]->getParams();
于 2009-09-14T14:55:06.613 に答える
10

DCMessageポインターのベクトルが必要です。

vector<DCMessage*> messages;
messages.push_back(new DCCmd(blah));

C ++のポリモーフィズムは、ポインターと参照を介してのみ機能し、これに参照を使用することはできません。だから、それはポインタです。

于 2009-09-14T14:56:09.390 に答える
3

(Kelixに投票しましたが、これにはもっと詳しく説明する必要があると思います)

あなたが探しているのは、抽象クラスから派生した任意のオブジェクトの要素のベクトルを作成することですよね?あなたが言うときvector <DCMessage>、あなたは代わりにクラスDCMessageの要素のベクトルを求めています。それは抽象クラスなので、それらを持つことはできません。

代わりにを要求する場合はvector <DCMessage *>、DCMessageから派生した任意のクラスのオブジェクトへのポインターを提供でき、実行時に呼び出されると、抽象ルーチンの正しい実装への動的(実行時)ディスパッチを取得します。

于 2009-09-14T15:09:25.253 に答える
2

ポリモーフィズムが必要な場合は、C ++のポインターが必要なので、抽象型へのポインターの両端キューを使用します(LIFOではなくFIFOキューであると想定しています)。次に、キュー内のメッセージの所有者を管理するという問題が発生します。

ただし、C ++はOOだけではなく、C++にはオブジェクトをストリームに書き込むためのイディオムがあります。メッセージキューがそれらをtcpポートに転送するだけの場合、またはと同様の動作をする場合は、オブジェクトへの参照を保存するのではなく、これらのイディオムを使用してデータをコピーすることをお勧めします。とにかくバイナリとの間でメッセージオブジェクトをマーシャリングする手法を実装している場合、キューが単なるバッファストリームであると、面倒な作業を省くことができます。

于 2009-09-14T15:04:40.470 に答える
0

他の回答は、抽象クラスのポインタしか持てないことを指摘しています。リストのようなコンテナでこれを使用する場合、要素を削除した後、手動でメモリも削除する必要があります。これは、コンテナの操作が、ポイントされているものではなく、ポインタ値自体に対してのみ機能するためです。

cpp-11ではunique_ptr<some_type>、ポインターを直接処理せずに、次のようなラッパーを使用して目標を達成できます。

list<unique_ptr<your_abstract_class>> someList;

someList.push_back(make_unique<your_derived_class>()); // will create new instance
someList.push_back(make_unique<your_other_derived_class>());

someList.pop_front(); // will remove the instance and automatically call its destructor

于 2020-07-07T10:41:49.973 に答える