Добавление элемента в список в C ++ - PullRequest
0 голосов
/ 26 января 2010

Я использую два класса в своем приложении C ++. Код выглядит следующим образом:

class MyMessageBox
{
public:
    void sendMessage(Message *msg, User *recvr);
    Message receiveMessage();
    list<Message> dataMessageList;
};

class User
{
public:
    MyMessageBox *dataMsgBox;
};

Сообщение является указателем на объект производного класса класса Message. Я реализовал функцию sendMessage следующим образом:

void MyMessageBox::sendMessage(Message *msg, User *recvr)
{
    Message &msgRef = *msg;
    recvr->dataMsgBox->dataMessageList.push_back(msgRef);
}

Когда я компилирую этот код, я получаю следующую ошибку: неопределенная ссылка на `vtable for Message '. Пожалуйста, помогите мне решить эту проблему.

Спасибо, Ракеш.

Ответы [ 5 ]

4 голосов
/ 26 января 2010

Я не знаю, что вы пытаетесь сделать с этим msgRef, но это неправильно. Вы случайно не программист на Java?

Если Message является базовым классом для производных от Message, вам нужно хранить указатели в списке. Измените list<Message> на list<Message*>; и push_back(msgRef) должно стать push_back(msg), полностью удалив код msgRef.

Кроме того, из соображений стиля плохая идея объединять множество операторов -> вместе. В этом случае лучше реализовать метод User, который добавляет Message в свой список и вызывает его.

1 голос
/ 26 января 2010

Для начала, если вы хотите хранить полиморфный объект в стандартном контейнере C ++, вы должны хранить указатель на объект, а не объект базового класса. Если вы этого не сделаете, вы столкнетесь с проблемами нарезки объектов. Кроме того, сделайте себе одолжение и оберните указатель в умный указатель, чтобы предотвратить утечку ресурсов - я бы рекомендовал boost :: shared_ptr <>.

Учитывая, что вы не показали нам код для Message, мы можем только догадываться, в чем проблема. Поскольку это относится к vtable, есть вероятность, что:

  • Вы не объявили ни одного члена класса Message как virtual. Было бы неплохо начать с деструктора
  • Вы забыли связать объектный файл, который содержит скомпилированный код для сообщения

Кстати, создание дополнительной ссылки в sendMessage() не является обязательным, и IMHO не совсем помогает читабельности. Просто отмените указатель msg в вашем вызове на push_back ().

0 голосов
/ 26 января 2010

Поскольку некоторые предлагают лучшие решения: проверьте std :: queue или std :: deque, чтобы поставить в очередь ваши сообщения. Итак, теперь у вас есть:

std::queue<std::tr1::shared_ptr<Message> > dataMessageQueue;
0 голосов
/ 26 января 2010

Если вы хотите обрабатывать вложенные сообщения, вам нужно использовать список указателей сообщений, а не объекты сообщений, и управлять их временем жизни. Для удобства я бы предложил сделать это

list< boost::shared_ptr<Message> > datamessageList

с использованием библиотеки boost . (И не для того, чтобы обидеть, но вам нужно немного больше прочитать о C ++ и указателях: похоже, что вы пробовали различные перестановки своего кода, пока не получили что-то скомпилированное ...)

0 голосов
/ 26 января 2010

Я думаю, что это слегка надуманное сообщение об ошибке, предполагающее, что вы не реализовали конструктор для своего класса сообщений. Посмотрите здесь и здесь на SO ...

Учитывая, что вы пытаетесь передать указатель на список объектов, компилятор, вероятно, жалуется, что не может преобразовать Message* в Message. Попробуйте изменить свой список на список Message*, как предлагает Kylotan.

Это ошибка компиляции или ссылки?

...