对 vtable 的未定义引用

新手上路,请多包涵

在构建我的 C++ 程序时,我收到错误消息

未定义的对 ‘vtable… 的引用

这个问题的原因是什么?我如何解决它?


碰巧我收到了以下代码的错误(有问题的类是 CGameModule。)我一生都无法理解问题所在。一开始还以为跟忘记给虚函数一个body有关,但据我了解,一切都在这里。继承链有点长,这里是相关源码。我不确定我应该提供哪些其他信息。

注意:构造函数似乎是发生此错误的地方。

我的代码:

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

继承自…

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

继承自….

 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

原文由 RyanG 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 923
2 个回答

所以,我已经弄清楚了这个问题,它是错误逻辑和不完全熟悉 automake/autotools 世界的结合。我将正确的文件添加到我的 Makefile.am 模板中,但我不确定构建过程中的哪个步骤实际创建了 makefile 本身。因此,我正在使用一个不知道我的新文件的旧 makefile 进行编译。

感谢您的回复和 GCC 常见问题解答的链接。我一定会阅读该内容以避免由于真正原因而发生此问题。

原文由 RyanG 发布,翻译遵循 CC BY-SA 2.5 许可协议

这是 GCC 中的错误功能。也就是说,G++ 编译器本身不能抱怨未定义的虚方法,因为它们可以在别处定义。但是 - 它不存储有关缺少哪些虚拟成员的信息;它只存储一个未定义的 vtable 符号,然后链接器会抱怨该符号。

相反,如果要列出缺失的成员,链接器可能会告诉您它们是什么。

有一个针对 GCC 的关于此问题的公开错误: 错误 42540 。不幸的是,它已经 13 岁了 :-(

原文由 einpoklum 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题