Lors de la construction de mon programme C++, je reçois le message d'erreur suivant
référence indéfinie à 'vtable...
Quelle est la cause de ce problème ? Comment puis-je le résoudre ?
Il se trouve que j'obtiens l’erreur pour le code suivant (La classe en question est CGameModule.) et je n’arrive pas à comprendre quel est le problème. Au début, je pensais que c'était lié à l'oubli de donner un corps à une fonction virtuelle, mais d'après ce que je comprends, tout est là. La chaîne d'héritage est un peu longue, mais voici le code source correspondant. Je ne suis pas sûr des autres informations que je devrais fournir.
Remarque : le constructeur est l'endroit où l'erreur se produit, semble-t-il.
Mon 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;
};
Hérite de...
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;
};
Qui hérite de....
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
La [FAQ GCC][1] contient une entrée à ce sujet :
La solution consiste à s'assurer que toutes les méthodes virtuelles qui ne sont pas pures sont définies. Notez qu'un destructeur doit être défini même s'il est déclaré pur-virtuel [class.dtor]/7.
J'ai donc trouvé la cause du problème, qui était une combinaison de mauvaise logique et de méconnaissance du monde d'automake/autotools. J’ajoutais les bons fichiers à mon modèle Makefile.am, mais je n’étais pas sûr de l’étape de notre processus de construction qui créait réellement le makefile lui-même. Ainsi, je compilais avec un ancien makefile qui n'avait aucune idée de mes nouveaux fichiers.
Merci pour les réponses et le lien vers la FAQ GCC. Je m'assurerai de le lire pour éviter que ce problème ne se produise pour une raison réelle.
CDasherComponent
a un corps pour le destructeur ? Ce n'est certainement pas ici. La question est de savoir si cela se trouve dans le fichier .cc.CDasherModule
devrait explicitement définir son destructeur virtual
.CGameModule
ait un }
supplémentaire à la fin (après le } ; // pour la classe
).CGameModule
est lié aux bibliothèques qui définissent CDasherModule
et CDasherComponent
?