当构建我的c++程序时,我得到了错误消息

未定义的引用'vtable…

这个问题的原因是什么?我该怎么解决呢?


碰巧,我得到以下代码的错误(类的问题是CGameModule.),我不能为我的生活理解问题是什么。起初,我认为这与忘记给虚拟函数赋予一个主体有关,但据我所知,一切都在这里。继承链有点长,但这里有相关的源代码。我不确定我还需要提供什么信息。

注意:这个错误似乎发生在构造函数中。

我的代码:

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

当前回答

FWIW我能够避免以下错误:

 ld: /usr/local/lib/libvmaf.a(svm.cpp.o):(.data.rel.ro._ZTI7QMatrix[_ZTI7QMatrix]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'

当将“C”项目与“c++”项目中的静态库链接时,通过在链接参数中添加-lstdc++。它是gcc -lstdc++,现在可以了。

最常见的方法是将-lstdc++添加到库的pkgconfig .pc文件库列表中。或者改用g++链接。

其他回答

我认为值得一提的是,当你试图链接到任何至少有一个虚方法的类的对象,而链接器无法找到该文件时,你也会得到这样的消息。 例如:

Foo.hpp:

class Foo
{
public:
    virtual void StartFooing();
};

Foo.cpp:

#include "Foo.hpp"

void Foo::StartFooing(){ //fooing }

编译:

g++ Foo.cpp -c

和main.cpp:

#include "Foo.hpp"

int main()
{
    Foo foo;
}

编译和链接:

g++ main.cpp -o main

给出我们最喜欢的错误:

/ tmp / cclKnW0g。o:在函数main': main.cpp:(.text+0x1a):未定义 参考vtable Foo' collect2: error: ld返回1退出 状态

我的理解是这样的:

Vtable在编译时为每个类创建 链接器不能访问Foo.o中的虚表

如果所有这些都失败了,那就寻找副本。我被构造函数和析构函数的显式初始引用误导了,直到我在另一篇文章中读到引用。它是任何未解的方法。在我的例子中,我以为我已经将使用char *xml作为参数的声明替换为使用不必要的麻烦的const char *xml的声明,但相反,我创建了一个新的声明,并将另一个声明保留在原处。

GCC FAQ中有一个条目:

解决方案是确保定义了所有非纯的虚方法。注意,即使析构函数被声明为pure-virtual [class.dtor]/7,也必须定义析构函数。

因此,你需要为虚析构函数提供一个定义:

virtual ~CDasherModule()
{ }

我刚刚遇到了另一个导致这个错误的原因,你可以检查一下。

基类将纯虚函数定义为:

virtual int foo(int x = 0);

子类有

int foo(int x) override;

问题是“=0”应该在括号外的拼写错误:

virtual int foo(int x) = 0;

所以,如果你向下滚动这么远,你可能没有找到答案,这是另一个需要检查的东西。

当我试图实现抽象工厂模式时,我也有这个问题,但忘记了链接一些库。因此,如果没有帮助喷射,检查是否所有必需的库都被链接