5

Неопределенная ссылка на виртуальную таблицу (vtable)

56

Когда я пытаюсь собрать свою программу на C++, я получаю сообщение об ошибке:

undefined reference to 'vtable...

В чем причина этой проблемы? Как мне это исправить?

К сожалению, я сталкиваюсь с этой ошибкой в следующем коде (класс, о котором идет речь — CGameModule), и никак не могу понять, в чем дело. Сначала я подумал, что это связано с тем, что я забыл дать реализацию виртуальной функции, но, насколько я понимаю, все здесь присутствует. Наследственная цепочка немного длинная, но вот соответствующий исходный код. Я не уверен, какую дополнительную информацию я должен предоставить.

Примечание: ошибка возникает в конструкторе, судя по всему.

Вот мой код:

cgamemodule.h

class CGameModule : public Dasher::CDasherComponent {
 public:
  CGameModule() : CDasherModule() {};
  virtual ~CGameModule();

  virtual void HandleEvent(Dasher::CEvent *pEvent);
};

cgamemodule.cpp

#include "cgamemodule.h"

void CGameModule::HandleEvent(Dasher::CEvent *pEvent) {}

Можно отметить, что CGameModule наследуется от...

namespace Dasher {
  class CEvent;
  class CDasherComponent;
};

class Dasher::CDasherComponent {
 public:
  CDasherComponent() {};
  virtual ~CDasherComponent() {};

  virtual void HandleEvent(Dasher::CEvent * pEvent) {};
};

Что может быть причиной ошибки, и как я могу её устранить?

5 ответ(ов)

1

Для справки, забытие определения виртуального деструктора приводит к следующему сообщению об ошибке:

неопределенная ссылка на `vtable для CYourClass'.

Я добавляю это примечание, потому что сообщение об ошибке может вводить в заблуждение. (Это было в версии gcc 4.6.3.)

0

Я разобрался с проблемой, и она оказалась результатом плохой логики и недостатка опыта в мире automake/autotools. Я добавлял правильные файлы в мой шаблон Makefile.am, но не знал, на каком этапе нашего процесса сборки фактически создаётся сам makefile. В итоге я компилировал с устаревшим makefile, который не имел представления о моих новых файлах.

Спасибо за ответы и ссылку на FAQ по GCC. Обязательно прочитаю его, чтобы избежать возникновения подобных проблем в будущем.

0

Если вы используете Qt, попробуйте повторно запустить qmake. Если эта ошибка возникает в классе виджета, возможно, qmake не заметил, что таблица виртуальных функций ui класса должна быть заново сгенерирована. Это помогло решить мою проблему.

0

Ошибка "Undefined reference to vtable" может возникнуть в следующей ситуации. Попробуйте следующий пример:

Класс A содержит:

virtual void functionA(parameters) = 0; 
virtual void functionB(parameters);

Класс B содержит:

  1. Определение для функции functionA.
  2. Определение для функции functionB.

Теперь вы пишете класс C, который будете наследовать от класса A.

Если вы попробуете скомпилировать, то получите ошибку "Undefined reference to vtable for Class C".

Причина:

functionA определена как чисто виртуальная, и её определение предоставлено в классе B. functionB определена как виртуальная (НО НЕ ЧИСТО ВИРТУАЛЬНАЯ), поэтому компилятор пытается найти её определение в классе A, хотя вы предоставили его в классе B.

Решение:

  1. Сделайте functionB чисто виртуальной (если это необходимо по вашей логике):
virtual void functionB(parameters) = 0;

(Это проверено и работает)

  1. Предоставьте определение для functionB в классе A, оставив его виртуальным. (Надеюсь, это сработает, хотя я это не проверял)
0

Вы получили эту ошибку, потому что ваш .cpp файл не был указан в makefile.

В общем, если вы забудете скомпилировать или связать определённый объектный файл, содержащий реализацию, вы столкнётесь с этой ошибкой. Убедитесь, что все необходимые файлы указаны в makefile, чтобы избежать подобных проблем.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь