缺少 vtable 通常意味着第一个非内联虚成员函数没有定义

Posted

技术标签:

【中文标题】缺少 vtable 通常意味着第一个非内联虚成员函数没有定义【英文标题】:A missing vtable usually means the first non-inline virtual member function has no definition 【发布时间】:2015-10-29 23:00:03 【问题描述】:

我很确定这个问题是重复的,但我的代码在这里不同,以下是我的代码。它失败并出现“未定义的符号”错误,不确定缺少什么。

class Parent 
   public :
     virtual int func () = 0;
     virtual ~Parent();

 ;


 class Child : public Parent 
     public :

     int data;
     Child (int k) 
        data = k;
      
    int func()    // virtual function
       cout<<"Returning square of 10\n";
        return 10*10;
    

    void Display () 
    cout<<data<<"\n";

 

 ~ Child() 

    cout<<"Overridden Parents Destructor \n";

 
;



int main() 
  Child a(10);
 a.Display();

 

以下是编译时的O/P。

Undefined symbols for architecture x86_64:
  "Parent::~Parent()", referenced from:
      Child::~Child() in inher-4b1311.o
  "typeinfo for Parent", referenced from:
      typeinfo for Child in inher-4b1311.o
  "vtable for Parent", referenced from:
      Parent::Parent() in inher-4b1311.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

【问题讨论】:

试试Parent::~Parent() = default; 【参考方案1】:

Parent::~Parent() 未定义。

你可以直接把定义放到类定义中:

class Parent 
   public :
     virtual int func () = 0;
     virtual ~Parent() ;
 ;

或者单独定义。或者,从 C++11 开始,写成virtual ~Parent() = default;

在任何情况下,析构函数都需要定义。

【讨论】:

这里可以完全避免析构函数吗? @Olshansk:如果您想在某个时候构建它,则不是。如果它是可构造的,它必须是可破坏的。 virtual 不会改变这一点。【参考方案2】:

为了帮助其他来这里寻求帮助的人 “注意:缺少 vtable 通常意味着第一个非内联虚拟成员函数没有定义。”

在我的情况下,错误是由缺少 = 0;在虚拟定义的末尾。确保所有适当的虚拟定义都有 = 0;最后。

virtual HRESULT function(int testInput) = 0;

希望这可以节省一些时间。

【讨论】:

"确保所有的虚拟定义都有 = 0; 最后"对不起, = 0 基本上是说这个虚拟函数是纯虚拟的,这反过来又会把 who 类变成抽象类, 这有时不是我们想要的。可以存在具有非纯虚函数的类。这个答案是绝对错误的 @Xavier。感谢您的反馈,我的回答清楚地表明“在我的情况下,错误是由......引起的。”它旨在帮助其他面临与我相同问题的人。它不是为了重新定义规范,只是清理并帮助解决错误消息的歧义。这并不会使答案绝对错误,尤其是当您说“有时并非如此”时,这意味着其他时候绝对会如此,因此对于这些情况是正确的。【参考方案3】:

值得补充的是,“无定义”也适用于空函数。

我有许多不同的子类,它们在每个子类中都实现了一个纯虚函数。当我浏览这些文件来实现函数时,我在.h 文件中声明了函数,并在.cpp 文件中定义了函数。我的计划是暂时将每个函数体留空,稍后再实现,因为我有很多实现要写。

但是,这不起作用。根据您使用的编译器,将删除没有主体的函数以尝试优化代码:

void foo() // removed 


因为foo被删除了,就好像你从来没有定义它,只是声明了它,因此“......虚拟成员函数没有定义。”

【讨论】:

以上是关于缺少 vtable 通常意味着第一个非内联虚成员函数没有定义的主要内容,如果未能解决你的问题,请参考以下文章

注意:缺少 vtable 通常意味着第一个非内联虚拟成员函数没有定义

iOS中的vtable错误

C++虚函数除了vtable怎么实现? [复制]

c++虚函数问题,大神请进

为啥即使不涉及虚函数,虚继承也需要vtable?

逆向第十九讲——类继承和成员类运算符重载模板逆向20171211