Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;,如何保存抽象类的列表?_C++_Oop_Inheritance_Pointers_Abstract - Fatal编程技术网

C++ 在C++;,如何保存抽象类的列表?

C++ 在C++;,如何保存抽象类的列表?,c++,oop,inheritance,pointers,abstract,C++,Oop,Inheritance,Pointers,Abstract,我有两个实现的类: class DCCmd : public DCMessage class DCReply : public DCMessage 两者都是双向发送和接收的协议消息 现在,在协议实现中,我需要创建一个消息队列,但由于DCMessage是抽象的,因此我无法执行以下操作: class DCMsgQueue{ private: vector<DCMessage> queue; public: DCMsgQueue(void); ~

我有两个实现的类:

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);
};
删除
=0
并在
DCMessage.cpp
中放置空的花括号可以解决问题,但这只是一个小技巧

另一个解决方案是,我应该创建两个dcmsgqueue:
DCCmdQueue
DCReplyQueue
,但这只是一些琐碎事情的重复代码。
有什么想法吗?=)

您无法实例化该对象,因为它是您所说的抽象对象。但是,您可以持有指向DCMessage类的指针向量,这将起作用,您只需要在将其推送到列表时添加内存地址,而不是对象

vector<DCMessage*> queue;

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

BYTE* params = queue[0]->getParams();
向量队列;
DCCmd*commandObject=新的DCCmd(…参数…);
queue.push_back(commandObject);
BYTE*params=队列[0]->getParams();

您需要DCMessage指针的向量:

vector<DCMessage*> messages;
messages.push_back(new DCCmd(blah));
向量消息;
消息。推回(新的DCCmd(blah));

<> C++中的多态性只通过指针和引用来工作,不能使用引用。所以,指针是。

如果你想要多态性,你需要C++中的指针,所以使用指针的抽象类型(假设它是一个FIFO队列而不是一个LIFO)。然后,您将遇到管理队列中消息的所有者的问题

<>但是,C++不仅仅是面向对象的,而且C++中有成语写到流的对象;如果消息队列只是将它们转发到tcp端口或具有类似的行为,则您可能希望使用这些习惯用法复制数据,而不是存储对对象的引用。如果您正在实现将消息对象打包到二进制文件或从二进制文件打包到二进制文件的技术,那么如果您的队列只是一个缓冲流,那么最终可能会为自己节省一些麻烦。

(投票支持Kelix,但我认为这需要进一步细化)

您要做的是创建元素向量,这些元素可以是从抽象类派生的任何对象的向量,对吗?当您说
vector
时,您要求的是类DCMessage元素的向量。您不能拥有它们,因为这是一个抽象类


如果您改为请求
vector
,那么您可以提供指向从DCMessage派生的任何类的对象的指针,并在运行时调用时将动态(运行时)分派到抽象例程的正确实现。

其他答案指出,您只能有抽象类的指针。当您在类似容器的列表中使用它时,在删除元素之后,您还必须手动删除它们的内存,因为容器操作只会处理指针值本身,而不会处理指向的对象

在cpp-11中,您可以使用像
unique\ptr
这样的包装器来实现您的目标,而无需直接处理指针:

vector<DCMessage*> messages;
messages.push_back(new DCCmd(blah));
list-someList;
someList.push_back(使_唯一());//将创建新实例
someList.push_back(使_唯一());
someList.pop_front();//将删除该实例并自动调用其析构函数

只需确保您没有存储堆栈分配对象的地址(当然,在从向量中删除对象之前,任何对象都将超出范围)。记住删除析构函数中的指针;您可能会希望实现复制构造函数和赋值运算符,以便在需要时获得深度复制;然而,我的命令很快就超出了范围,所以我需要考虑这一点。我有一段时间没有可调试的源代码了,现在非常感谢。多态性将与引用一起使用。然而,你不能存储它们。你说的和我写的有什么不同?因为某种原因,当我读到它时,我跳过了“和引用”。再加上“你不能使用参考资料”,我认为这是一个错误。我羞愧地收回我的评论。:)我需要随机访问队列中的元素,我在cplusplus.com的参考资料中读到向量是更好的选择。由于协议规范中的原因,仅仅缓冲是不起作用的。如果您需要随机索引到“队列”,那么是的,向量更好。如果只需要在中间找到元素(通过迭代结构),那么它就不重要了。“”Duk(1)非常像向量:它是一个支持随机访问元素、在序列末尾插入和移除元素的序列,和线性时间插入和去除的元素在中间。deque不同于vector的主要方式是,deque还支持在序列开始时对元素进行恒定时间的插入和移除[2]。“谢谢,但你的意思是我“提供对对象的引用”吗?”?这让人困惑,也许吧,奥马尔。很抱歉,我从C++语言中看到的是更平淡无奇的语言,所以<代码>和Foo>代码>永远是“Foo的指针”。