搞清虚析构函数的使用场合
作者:网络转载 发布时间:[ 2013/2/18 10:50:04 ] 推荐标签:
马上要找工作了,开始复习一下c/c++基础知识了。看到虚析构这一块,产生几个疑问,发现自己以前的理解还不够透彻,写了几个程序测试验证了一下,终于算搞清楚了。
疑问:什么情况下必须用虚析构?
先看个例子:
#include <iostream>
class A
{
public:
A(){};
~A()
{
std::cout << "~A" << std::endl;
};
private:
int a;
};
class B : public A
{
public:
B(){};
~B()
{
std::cout << "~B" << std::endl;
}
private:
int b;
};
int main()
{
B b;
return 0;
}
调试发现,窗口依次输出: ~B 和 ~A,也是说,B类对象b析构的时候,先调用了B类的析构函数,然后调用了基类的析构函数。
如果 main 函数中的代码,替换为如下呢?
int main()
{
A *pb = new B();
delete pb;
return 0;
}
你会发现,还是依次输出了 ~B 和 ~A,也是说,当使用子类指针指向子类对象的时候,析构的时候,依然会依次调用子类和基类的析构函数。
如果 main 函数中的代码,替换为如下呢?
int main()
{
A * pa = new B();
delete pa;
return 0;
}
调试发现,这份代码,只会输出 ~A, 哦,到此终于明白了,当用基类指针指向派生类对象时,如果基类析构函数不设置为 virtual 的话,则在 delete 基类指针的时候,无法成功调用子类的析构函数。这才是虚析构函数发挥作用的真正场合。
上述代码解决方法:把基类 A 的析构函数设置为virtual,则可以成功实现delete pa的时候依次调用B类和A类的析构函数了。
那么,进一步讲,我们是否应该把所有类的析构函数都设置为虚析构呢?
不应该,这样设置不合理,只有在该类可能作为基类的情况下,并且可能使用到多态特性的时候,才有必要把基类的析构函数设置为虚析构,否则,没有必要,因为设置为虚析构会产生额外的开销,即下一个问题:
一个类如果把析构函数设置为 virtual 是否也会产生虚函数表?
我们把上述代码稍微改一下:
class A
{
public:
A(){};
~A()
{
std::cout << "~A" << std::endl;
};
void test()
{
std::cout << "~test" << std::endl;
}
private:
int a;
};
int main()
{
std::cout << sizeof(A) << std::endl;
}
如果 ~A前面不加virtual,则输出的结果是:4
如果 ~A前面加virtual,则输出的结果是:8
可以得出如下结论:
(1)如果类没有virtual成员函数时,类的大小由数据成员大小决定
(2)虚析构函数也会使类产生虚函数表,并且虚函数表的大小是 4 字节
好啦,大致写这么多了,算是复习过程中留下的笔记,希望对C++新手有所帮助,有疑问欢迎留言探讨。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11