Référence indéfinie à vtable

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&#8217erreur pour le code suivant (La classe en question est CGameModule.) et je n&#8217arrive 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.

[1] : http://gcc.gnu.org/faq.html#vtables

Commentaires (9)
Solution

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&#8217ajoutais les bons fichiers à mon modèle Makefile.am, mais je n&#8217étais pas sûr de l&#8217é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.

Commentaires (7)
  • Etes-vous sûr que 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.
  • D'un point de vue stylistique, CDasherModule devrait explicitement définir son destructeur virtual.
  • Il semble que CGameModule ait un } supplémentaire à la fin (après le } ; // pour la classe).
  • Est-ce que CGameModule est lié aux bibliothèques qui définissent CDasherModule et CDasherComponent ?
Commentaires (2)