Beim Erstellen meines C++-Programms erhalte ich die Fehlermeldung
undefinierte Referenz auf 'vtable...
Was ist die Ursache für dieses Problem? Wie kann ich es beheben?
Es ist so, dass ich den Fehler für den folgenden Code (Die Klasse in Frage ist CGameModule.) und ich kann nicht für das Leben von mir verstehen, was das Problem ist. Zuerst dachte ich, dass es damit zusammenhängt, dass ich vergessen habe, einer virtuellen Funktion einen Körper zu geben, aber soweit ich das verstehe, ist alles da. Die Vererbungskette ist ein wenig lang, aber hier ist der zugehörige Quellcode. Ich bin mir nicht sicher, welche anderen Informationen ich bereitstellen sollte.
Hinweis: Der Konstruktor ist der Ort, an dem dieser Fehler auftritt.
Mein Code:
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;
};
Erbt von...
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;
};
Das erbt von....
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
Die GCC FAQ hat einen Eintrag dazu:
Die Lösung besteht darin, sicherzustellen, dass alle virtuellen Methoden, die nicht rein sind, definiert werden. Beachten Sie, dass ein Destruktor definiert werden muss, auch wenn er als rein-virtuell deklariert ist [class.dtor]/7.
Also, ich habe das Problem herausgefunden und es war eine Kombination aus schlechter Logik und nicht ganz vertraut mit der automake/autotools Welt. Ich fügte die richtigen Dateien zu meiner Makefile.am-Vorlage hinzu, aber ich war mir nicht sicher, welcher Schritt in unserem Build-Prozess tatsächlich das Makefile selbst erstellt. Ich kompilierte also mit einem alten Makefile, das keine Ahnung von meinen neuen Dateien hatte.
Vielen Dank für die Antworten und den Link zu den GCC-FAQ. Ich werde das auf jeden Fall lesen, um zu vermeiden, dass dieses Problem aus einem echten Grund auftritt.
CDasherComponent
einen Body für den Destruktor hat? Hier ist er definitiv nicht - die Frage ist, ob er in der .cc-Datei ist.CDasherModule
seinen Destruktor virtual
explizit definieren.CGameModule
ein extra }
am Ende hat (nach dem }; // für die Klasse
).CGameModule
gegen die Bibliotheken gelinkt, die CDasherModule
und CDasherComponent
definieren?