Когато изграждам програмата си на C++, получавам съобщението за грешка
недефинирана референция към 'vtable...
Каква е причината за този проблем? Как да го отстраня?
Получава се така, че получавам грешка за следния код (въпросният клас е CGameModule.) и не мога да разбера какъв е проблемът. Отначало си помислих, че е свързан с това, че съм забравил да дам тяло на виртуална функция, но доколкото разбирам, всичко е наред. Веригата на наследяване е малко дълга, но ето свързания с нея изходен код. Не съм сигурен каква друга информация трябва да предоставя.
Забележка: Изглежда, че конструкторът е мястото, където се случва тази грешка.
Моят код:
class CGameModule : public CDasherModule {
public:
CGameModule(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName)
: CDasherModule(pEventHandler, pSettingsStore, iID, 0, szName)
{
g_pLogger->Log("Inside game module constructor");
m_pInterface = pInterface;
}
virtual ~CGameModule() {};
std::string GetTypedTarget();
std::string GetUntypedTarget();
bool DecorateView(CDasherView *pView) {
//g_pLogger->Log("Decorating the view");
return false;
}
void SetDasherModel(CDasherModel *pModel) { m_pModel = pModel; }
virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
CDasherNode *pLastTypedNode;
CDasherNode *pNextTargetNode;
std::string m_sTargetString;
size_t m_stCurrentStringPos;
CDasherModel *m_pModel;
CDasherInterfaceBase *m_pInterface;
};
Наследява от...
class CDasherModule;
typedef std::vector<CDasherModule*>::size_type ModuleID_t;
/// \ingroup Core
/// @{
class CDasherModule : public Dasher::CDasherComponent {
public:
CDasherModule(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, int iType, const char *szName);
virtual ModuleID_t GetID();
virtual void SetID(ModuleID_t);
virtual int GetType();
virtual const char *GetName();
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount) {
return false;
};
private:
ModuleID_t m_iID;
int m_iType;
const char *m_szName;
};
Което наследява от....
namespace Dasher {
class CEvent;
class CEventHandler;
class CDasherComponent;
};
/// \ingroup Core
/// @{
class Dasher::CDasherComponent {
public:
CDasherComponent(Dasher::CEventHandler* pEventHandler, CSettingsStore* pSettingsStore);
virtual ~CDasherComponent();
void InsertEvent(Dasher::CEvent * pEvent);
virtual void HandleEvent(Dasher::CEvent * pEvent) {};
bool GetBoolParameter(int iParameter) const;
void SetBoolParameter(int iParameter, bool bValue) const;
long GetLongParameter(int iParameter) const;
void SetLongParameter(int iParameter, long lValue) const;
std::string GetStringParameter(int iParameter) const;
void SetStringParameter(int iParameter, const std::string & sValue) const;
ParameterType GetParameterType(int iParameter) const;
std::string GetParameterName(int iParameter) const;
protected:
Dasher::CEventHandler *m_pEventHandler;
CSettingsStore *m_pSettingsStore;
};
/// @}
#endif
В GCC FAQ има статия за това:
Решението е да се гарантира, че всички виртуални методи, които не са чисти, са дефинирани. Обърнете внимание, че деструктор трябва да бъде дефиниран, дори ако е деклариран като чисто виртуален [class.dtor]/7.
Така че, разбрах проблема и това беше комбинация от лоша логика и не съм напълно запознат със света на automake/autotools. Добавях правилните файлове към шаблона Makefile.am, но не бях сигурен коя стъпка от процеса на изграждане всъщност създава самия makefile. Така че компилирах със стар makefile, който нямаше никаква представа за новите ми файлове.
Благодаря за отговорите и за връзката към често задаваните въпроси на GCC. Задължително ще го прочета, за да избегна появата на този проблем по реална причина.
CDasherComponent
има тяло за деструктора? Със сигурност не е тук - въпросът е дали е в .cc файла.CDasherModule
трябва изрично да дефинира своя деструктор virtual
.CGameModule
има допълнителен }
в края (след }; // за класа
).CGameModule
се свързва с библиотеките, които дефинират CDasherModule
и CDasherComponent
?