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  析构函数地址

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


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

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


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


子类的虚函数wohs也出来了

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

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

老规矩,反汇编走起


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


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

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

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

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值