我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。

可是,为什么要这样做呢?下面用一个小例子来说明:

 #include<iostream>
using namespace std;
class Base
{
public:
Base() {}
virtual ~Base();
}; class Subclass :public Base
{
public:
Subclass() {}
~Subclass();
};
Base::~Base()
{
cout << "Base destructor is called." << endl;
} Subclass::~Subclass()
{
cout << "Subclass destructor is called." << endl;
} int main()
{
Base *b = new Subclass;
delete b;
return ;
}

输出结果:

Subclass destructor is called.
Base destructor is called.

这个很简单,非常好理解。
但是,如果把类Base析构函数前的virtual去掉,那输出结果就是下面的样子了:

Base destructor is called.

也就是说,类Base的析构函数根本没有被调用!一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏。我想所有的C++程序员都知道这样的危险性。当然,如果在析构函数中做了其他工作的话,那你的所有努力也都是白费力气。
    所以,文章开头的那个问题的答案就是--这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。
    当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。

c++虚析构函数的必要性的更多相关文章

  1. C++学习24 虚析构函数

    在C++中,构造函数用于在创建对象时进行初始化工作,不能声明为虚函数.因为在执行构造函数前对象尚未创建完成,虚函数表尚不存在,也没有指向虚函数表的指针,所以此时无法查询虚函数表,也就不知道要调用哪一个 ...

  2. 4.4 C++虚析构函数

    参考:http://www.weixueyuan.net/view/6373.html 总结: 构造函数是不能声明为虚函数的,析构函数可以被声明为虚函数. 将基类的析构函数声明为虚函数之后,派生类的析 ...

  3. c++虚析构函数

    虚析构函数的作用主要是当通过基类指针删除派生类对象时,调用派生类的析构函数(如果没有将不会调用派生类析构函数) #include <iostream> using namespace st ...

  4. EC笔记,第二部分:7.为多态基类声明虚析构函数

    7.为多态基类声明虚析构函数 1.为多态基类声明虚析构函数 code1: class A{ public: int* a; A():a(new int(5)) {} ~A(){ delete a; } ...

  5. C++浅析——继承类内存分布和虚析构函数

    继承类研究 1. Code 1.1 Cbase, CTEST为基类,CTest2为其继承类,并重新申明了基类中的同名变量 class CBase { public: int Data; CBase() ...

  6. 虚析构函数(√)、纯虚析构函数(√)、虚构造函数(X)

    from:http://blog.csdn.net/fisher_jiang/article/details/2477577 一. 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有 ...

  7. 从零开始学C++之虚函数与多态(一):虚函数表指针、虚析构函数、object slicing与虚函数

    一.多态 多态性是面向对象程序设计的重要特征之一. 多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态的实现: 函数重载 运算符重载 模板 虚函数 (1).静态绑定与动态绑 ...

  8. 从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数

    一.纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 在基类中不能给出有意义 ...

  9. C/C++中的虚析构函数和私有析构函数的使用

    代码: #include <iostream> using namespace std; class A{ public: A(){ cout<<"construct ...

随机推荐

  1. Spring 框架控制器类方法可用的参数与返回类型

    参数类型 Spring 有内建的 HTTP 消息转换器用于部分简单类型之间的转换 标准 Servlet 类型:HttpServletRequest, HttpServletResponse, Http ...

  2. windows下subversion服务器搭建

    一.下载subversion服务器端和客户端软件 1.subversion下载地址:http://subversion.tigris.org/ 2.svn比较流行的客户端Tortoisesvn下载地址 ...

  3. c/c++不能返回局部对象和局部变量的指针或引用解释

    在编写c/c++代码时,调用函数的书写让程序变得整洁易读,但是调用函数的返回值(局部变量的返回值,变量,结构体,数组等)也有注意事项.c/c++严禁返回局部变量的指针或引用. 其实函数的返回值的规则非 ...

  4. Excel拼接字符串

             有时候,需要把一些Excel表格中的内容进行拼接,比如A4行的值是前面三行值的加起来.在Excel中可以使用&来进行这种操作.如果数据非常多,就可以使用这个来进行批量操作.

  5. js面向对象过程

    var a = new  b(); 等价于 var a={}; a=b.prototype; b.call(a);

  6. 「日常训练」「小专题·USACO」 Broken Necklace(1-2)

    题意 圆形链条,打断一处可以形成一条链.问在哪个地方开始打断,能够形成最大的连续颜色(白色视作同样的颜色)? 分析 说起来很高级,但是我们实际上并不需要穷举打断的地方,只需要把串重复三回啊三回.然后从 ...

  7. 问题 C: Goldbach's Conjecture

    题目描述 Goldbach's Conjecture: For any even number n greater than or equal to 4, there exists at least ...

  8. 《机器学习实战》 in python3.x

    机器学习实战这本书是在python2.x的环境下写的,而python3.x中好多函数和2.x中的名称或使用方法都不一样了,因此对原书中的内容需要校正,下面简单的记录一下学习过程中fix的部分 1.pr ...

  9. UVa 294 - Divisors 解题报告 c语言实现 素数筛法

    1.题目大意: 输入两个整数L.H其中($1≤L≤H≤10^9,H−L≤10000$),统计[L,H]区间上正约数最多的那个数P(如有多个,取最小值)以及P的正约数的个数D. 2.原理: 对于任意的一 ...

  10. web3无法安装的额解决方案-----yarn命令安装web3

    凡是可以用 JavaScript 来写的应用,最终都会用 JavaScript 来写. --Atwood定律(Jeff Atwood在2007年提出) yarn命令详解 https://yarnpkg ...