Undefined reference to vtable

2018-12-31 09:23发布

So, I'm getting the infamously horrible

undefined reference to 'vtable...

error for the following code (The class in question is CGameModule.) and I cannot for the life of me understand what the problem is. At first, I thought it was related to forgetting to give a virtual function a body, but as far as I understand, everything is all here. The inheritance chain is a little long, but here is the related source code. I'm not sure what other information I should provide.

Note: The constructor is where this error is happening, it'd seem.

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

Inherits from...

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

Which inherits from....

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

标签: c++ gcc g++
27条回答
倾城一夜雪
2楼-- · 2018-12-31 09:37

Not to cross post but. If you are dealing with inheritance the second google hit was what I had missed, ie. all virtual methods should be defined.

Such as:

virtual void fooBar() = 0;

See answare C++ Undefined Reference to vtable and inheritance for details. Just realized it's already mentioned above, but heck it might help someone.

查看更多
美炸的是我
3楼-- · 2018-12-31 09:37

I got this error in the following scenario

Consider a case where you have defined the implementation of member functions of a class in the header file itself. This header file is an exported header (in other words, it might be copied to some common/include directly in your codebase). Now you have decided to separate the implementation of the member functions to to .cpp file. After you separated/moved the implementation to .cpp, the header file now has just the prototypes of the member functions inside the class. After the above changes, if you build your codebase you may get the "undefined reference to 'vtable..." error.

To fix this, before building, make sure you delete the header file (to which you made changes) in common/include directory. Also make sure you change your makefile to accomodate/add the new .o file that is built from the new .cpp file you just created. When you do these steps the compiler/linker will no longer complain.

查看更多
笑指拈花
4楼-- · 2018-12-31 09:37

I simply got this error because my cpp file was not in the makefile.

查看更多
素衣白纱
5楼-- · 2018-12-31 09:40

In my case I'm using Qt and had defined a QObject subclass in a foo.cpp (not .h) file. The fix was to add #include "foo.moc" at the end of foo.cpp.

查看更多
几人难应
6楼-- · 2018-12-31 09:41

Ok, the solution to this is that you may have missed out on the definition. See the example below to avoid the vtable compiler error:

// In the CGameModule.h

class CGameModule
{
public:
    CGameModule();
    ~CGameModule();

    virtual void init();
};

// In the CGameModule.cpp

#include "CGameModule.h"

CGameModule::CGameModule()
{

}

CGameModule::~CGameModule()
{

}

void CGameModule::init()    // Add the definition
{

}
查看更多
初与友歌
7楼-- · 2018-12-31 09:42

Undefined reference to vtable may occur due to the following situation also. Just try this:

Class A Contains:

virtual void functionA(parameters)=0; 
virtual void functionB(parameters);

Class B Contains:

  1. The definition for the above functionA.
  2. The definition for the above functionB.

Class C Contains: Now you're writing a Class C in which you are going to derive it from Class A.

Now if you try to compile you will get Undefined reference to vtable for Class C as error.

Reason:

functionA is defined as pure virtual and its definition is provided in Class B. functionB is defined as virtual (NOT PURE VIRTUAL) so it tries to find its definition in Class A itself but you provided its definition in Class B.

Solution:

  1. Make function B as pure virtual (if you have requirement like that) virtual void functionB(parameters) =0; (This works it is Tested)
  2. Provide Definition for functionB in Class A itself keeping it as virtual . (Hope it works as I didn't try this)
查看更多
登录 后发表回答