簡體   English   中英

在 C++ 中,如何保存抽象類的列表?

[英]In C++, how can I hold a list of an abstract class?

我有兩個實現的類:

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放置空花括號DCMessage.cpp解決問題,但這只是一個技巧。

另一個解決方案是我應該制作兩個 DCMsgQueues: DCCmdQueueDCReplyQueue ,但這只是一些瑣碎的重復代碼。 有任何想法嗎? =)

您無法實例化該對象,因為它如您所說是抽象的。 但是,您可以保存一個指向 DCMessage 類的指針向量,該類將起作用,您只需要在將其推送到列表時添加內存地址而不是對象。

vector<DCMessage*> queue;

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

BYTE* params = queue[0]->getParams();

你想要一個 DCMessage 指針向量:

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

C++ 中的多態僅通過指針和引用起作用,並且您不能為此使用引用。 所以,指針是。

(投票支持 Kelix,但我認為這需要更多詳細說明)

您要做的是創建一個元素向量,該向量可以是從抽象類派生的任何對象,對嗎? 當您說vector <DCMessage> ,您實際上要求的是 DCMessage 類元素的向量。 你不能擁有它們,因為那是一個抽象類。

如果您改為請求vector <DCMessage *> ,那么您可以提供指向從 DCMessage 派生的任何類的對象的指針,並且在運行時調用時將動態(運行時)分派到您的抽象例程的正確實現。

如果您想要多態性,則需要 C++ 中的指針,因此將使用指向抽象類型的指針的雙端隊列(假設它是 FIFO 隊列而不是 LIFO )。 然后,您就會遇到管理誰擁有隊列中消息的問題。

然而,C++ 不僅僅是關於 OO,而且 C++ 中有用於將對象寫入流的習慣用法; 如果消息隊列只是將它們轉發到 tcp 端口或具有類似於 的行為,則您可能希望使用這些習語並復制數據,而不是存儲對對象的引用。 如果您正在實施將消息對象編組到二進制或從二進制編組的技術,如果您的隊列只是一個緩沖流,您最終可能會為自己省去一些麻煩。

其他答案指出您只能擁有抽象類的指針。 當您在像列表這樣的容器中使用它時,在刪除元素后,您還必須手動刪除它們的內存,因為容器操作將只處理指針值本身而不是指向的值。

在 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

暫無
暫無

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

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