c++虚析构函数在虚函数表中吗?

先放结论:在的!

而且与声明的先后顺序有关

为什么有这个疑问呢?因为析构函数的名字不一样啊......(好吧,是我too young了)

实验代码的继承关系如下:

class fa{
public:
     fa(){}
     virtual ~fa(){cout << "des fa" << endl;}
     virtual show(){cout << "fa show" << endl;}
     virtual wohs(){cout << "fa wohs" << endl;}
};

class son : public fa{
public:
     son(){}
     virtual ~son(){cout << "des son" << endl;}
     virtual show(){cout << "son show" << endl;}
     virtual wohs(){cout << "son wohs" << endl;}
};

先对一个对函数指针改改名,方便定义:

typedef void(* func)(void);

虽然c++标准明确规定不能获取构造函数和析构函数的地址,但是这一切在指针的面前都是浮云(论指针的可怕之处......)

int main()
{
     son boy;

     func fff;
     fff = (func)*(int *)((char*)(*(int *)&boy));
     /*
          vptr在实例对象地址的开头,
          跟着这个地址走到虚函数表,
          获取表中的函数地址,
          跟着这个地址走,来到函数的开头,
          把这个地址交给fff
     */
     fff();

     return 0;
}

然后成功地发现析构函数调用了两次,一次是fff调的,一次是return时调的,至于fff是什么类型的函数指针?随意,反正到最后

汇编时都会变成:call  析构函数地址

c++虚析构函数在虚函数表中吗?_第1张图片

我们来试试虚函数表的下一个函数,即:fff = (func)*(int *)((char*)(*(int *)&boy + 4));

c++虚析构函数在虚函数表中吗?_第2张图片

怎么还是析构......(经过试验,虚析构函数占两个位,不知道为什么......)

那再试下下一个,下两个......

c++虚析构函数在虚函数表中吗?_第3张图片

好,子类的虚函数show出来了

c++虚析构函数在虚函数表中吗?_第4张图片

子类的虚函数wohs也出来了

可见虚析构函数真的在虚函数表,而且和声明顺序有关(这个可以自己试验下)

然后还有个问题,既然子类的虚函数表中只有子类虚析构函数,那它怎样析构父类呢?父类的析构函数又在哪呢?

老规矩,反汇编走起

c++虚析构函数在虚函数表中吗?_第5张图片

下一部,进入到子类的析构函数:

c++虚析构函数在虚函数表中吗?_第6张图片

然后惊喜地发现,在子类的析构函数中包含着对父类析构函数的调用

总结:虚析构函数的地址存在于虚函数表中,和普通虚函数别无二致,同时也会像普通的虚函数一样进行覆盖

虽然父子的析构函数名字不一样,但是他们占同一个坑(即父子析构函数在虚函数表中的位置是一样的,否则就不存在多态了)

析构时,到特定的坑中调用该类型的析构函数,其析构函数中又嵌套了很多对父类的析构函数的调用

你可能感兴趣的:(c++虚析构函数在虚函数表中吗?)