我在C ++应用程序中使用了两个类。代码如下:
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
list<Message> dataMessageList;
};
class User
{
public:
MyMessageBox *dataMsgBox;
};
msg是指向Message类的派生类对象的指针。我已经实现了sendMessage函数,如下所示:
void MyMessageBox::sendMessage(Message *msg, User *recvr)
{
Message &msgRef = *msg;
recvr->dataMsgBox->dataMessageList.push_back(msgRef);
}
编译此代码时,出现以下错误: 未定义的引用`vtable for Message'。请帮我解决这个问题。
谢谢, 勒凯什。
答案 0 :(得分:4)
我不知道你要用msgRef做什么,但这是错的。你是一名前任Java程序员吗?
如果Message
是Message
衍生词的基类,则需要在列表中存储指针。将list<Message>
更改为list<Message*>
;并且push_back(msgRef)
应该变为push_back(msg)
,完全删除msgRef
代码。
另外,作为一种风格问题,将许多->
运算符链接在一起是个坏主意。在这种情况下,最好在User
上实现一个方法,将Message
添加到自己的列表中并调用它。
答案 1 :(得分:1)
对于初学者,如果要将多态对象存储在标准C ++容器中,则应存储指向对象的指针,而不是基类的对象。如果不这样做,则会遇到对象切片问题。另外,帮自己一个忙,并将指针包装在智能指针中以防止资源泄漏 - 我建议使用boost :: shared_ptr&lt;&gt;。
鉴于您没有向我们展示Message的代码,我们可以猜出问题是什么。因为它指的是vtable,很可能是:
virtual
。从析构函数开始是个好主意顺便说一句,在sendMessage()
中创建附加引用是没有必要的,恕我直言并不完全有助于提高可读性。只需在调用push_back()时取消引用msg指针。
答案 2 :(得分:0)
我认为这是一个有点人为的错误消息,表明您没有为您的消息类实现构造函数。看看here和here on SO ...
鉴于您正在尝试将指针传递给对象列表,编译器可能会抱怨它无法将Message*
转换为Message
。尝试将列表更改为Kylotan建议的Message*
列表。
是编译错误还是链接错误?
答案 3 :(得分:0)
如果要处理子类消息,则需要使用Message指针列表而不是Message对象,并管理它们的生命周期。为方便起见,我建议制作
list< boost::shared_ptr<Message> > datamessageList
使用boost库。 (而且不要冒犯,但你需要阅读更多有关C ++和指针的信息:看起来你尝试了各种代码的排列,直到你得到了编译的东西......)
答案 4 :(得分:0)
正如一些人提出了更好的解决方案:检查std :: queue或std :: deque来排队你的消息。所以现在你有了:
std::queue<std::tr1::shared_ptr<Message> > dataMessageQueue;