0

我在我的 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”的引用。请帮我解决这个问题。

谢谢,拉克什。

4

5 回答 5

4

我不知道你想用那个 msgRef 做什么,但这是错误的。你是一名前 Java 程序员吗?

如果Message是 的派生类的基类Message,则需要将指针存储在列表中。更改list<Message>list<Message*>; 并且push_back(msgRef)应该成为push_back(msg),完全删除msgRef代码。

此外,就风格而言,将许多->运算符链接在一起是一个坏主意。User在这种情况下,最好实现一个方法,将 a 添加Message到自己的列表中并调用它。

于 2010-01-26T11:48:54.313 回答
1

对于初学者,如果您想在标准 C++ 容器中存储多态对象,您应该存储指向该对象的指针,而不是基类的对象。如果不这样做,就会遇到对象切片问题。另外,帮自己一个忙,将指针包装在智能指针中以防止资源泄漏——我建议使用 boost::shared_ptr<>。

鉴于您尚未向我们展示 Message 的代码,我们只能猜测问题所在。因为它指的是一个 vtable,所以很可能是:

  • 您没有将 Message 的任何类成员声明为virtual. 从析构函数开始是个好主意
  • 您忘记链接包含已编译的 Message 代码的目标文件

顺便说一句,在其中创建额外的参考sendMessage()是不必要的,恕我直言并不能完全提高可读性。只需在调用 push_back() 时取消引用 msg 指针。

于 2010-01-26T11:55:04.820 回答
0

我认为这是一条略微做作的错误消息,表明您尚未为消息类实现构造函数。在这里和这里看看SO ...

鉴于您试图将指针传递给对象列表,编译器可能会抱怨它无法转换Message*Message. 尝试将您的列表更改Message*为 Kylotan 建议的列表。

是编译错误还是链接错误?

于 2010-01-26T11:48:07.223 回答
0

如果要处理子类消息,则需要使用消息指针列表而不是消息对象,并管理它们的生命周期。为方便起见,我建议制作它

list< boost::shared_ptr<Message> > datamessageList

使用boost库。(不要冒犯,但你确实需要阅读更多关于 C++ 和指针的内容:看起来你尝试了代码的各种排列,直到你得到编译的东西......)

于 2010-01-26T11:51:04.113 回答
0

由于有些人提出了更好的解决方案:查看 std::queue 或 std::deque 以将您的消息排队。所以现在你有:

std::queue<std::tr1::shared_ptr<Message> > dataMessageQueue;
于 2010-01-26T12:03:35.847 回答