Nedefinirana referenca na vtable

Pri gradnji programa C++ dobim sporočilo o napaki

nedefinirana referenca na 'vtable...

Kaj je vzrok za to težavo? Kako jo lahko odpravim?


Zgodilo se je, da sem dobil napako za naslednjo kodo (Zadevni razred je CGameModule.) in ne morem razumeti, v čem je težava. Najprej sem mislil, da je povezana s tem, da sem navidezni funkciji pozabil dati telo, vendar, kolikor razumem, je tu vse v redu. Veriga dedovanja je nekoliko dolga, vendar je tukaj povezana izvorna koda. Nisem prepričan, katere druge informacije bi moral navesti.

Opomba: Zdi se, da se ta napaka zgodi v konstruktorju.

Moja koda:

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;
};

Deduje od...

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;
};

Ki deduje od....

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

V Pogosta vprašanja GCC je o tem zapis:

Rešitev je zagotoviti, da so definirane vse virtualne metode, ki niso čiste. Upoštevajte, da mora biti destruktor definiran, tudi če je deklariran kot čisto virtualni [class.dtor]/7.

Komentarji (9)
Rešitev

So, I've ugotovili težavo in to je bila kombinacija slabe logike in ni popolnoma seznanjen s svetom automake/autotools. V predlogo Makefile.am sem dodal pravilne datoteke, vendar nisem bil prepričan, kateri korak v našem postopku sestavljanja dejansko ustvari samo datoteko makefile. Tako sem sestavljal s staro datoteko makefile, ki ni imela pojma o mojih novih datotekah.

Hvala za odgovore in povezavo do pogostih vprašanj GCC. To bom zagotovo prebral, da se izognem tej težavi, ki bi se pojavila iz pravega razloga.

Komentarji (7)
  • Ali ste prepričani, da ima CDasherComponent telo za destruktor? Tukaj zagotovo ni - vprašanje je, ali je v datoteki .cc.
  • Z vidika sloga bi moral CDasherModule izrecno opredeliti svoj destruktor virtual.
  • Videti je, kot da ima CGameModule na koncu dodaten } (za }; // za razred).
  • Ali se CGameModule povezuje s knjižnicami, ki opredeljujejo CDasherModule in CDasherComponent?
Komentarji (2)