先看下面一段程序:

#include <iostream>
using namespace std;class Person
{
public:
virtual ~Person()                    //加了virtual,讲析构函数声明为虚函数
{cout << "Person::~Person()" << endl;
}
};class Student : public Person
{
public:
~Student()                                 // virtual可加可不加
{cout << "Student::~Student()" << endl;
}
};int main()
{
Person *pt1 = new Person;
Person *pt2 = new Student;          // 用基类的指针指向子类
// Student *pt3 = new Person;     // 不能用子类指针指向基类,错误!
Student *pt4 = new Student;delete pt1;
cout << "*********" << endl;
delete pt2;
cout << "*********" << endl;
//delete pt3;
//cout << "*********" << endl;
delete pt4;
cout << "*********" << endl;return 0;
}

运行结果:
Person::~Person()

***********

Student::~Student()

Person::~Person()

**********

Student::~Student()

Person::~Person()

**********

如果在基类中析构函数不加virtual,结果为:

Person::~Person()

***********

Person::~Person()

**********

Student::~Student()

Person::~Person()

**********



可以看出:只有在用基类的指针指向派生类的时候,才会出现这种情况。因为这个时候虚函数发挥了动态的作用。

析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。

如果在上面的例子中,基类中未定义virtual析构函数,而派生类中定义了virtual的析构函数,此时用基类指针指向派生类,再delete掉,

即:

class Person
{
public:
~Person()                    {cout << "Person::~Person()" << endl;
}
};class Student : public Person
{
public:
virtual ~Student()                                {cout << "Student::~Student()" << endl;
}
};Person * pt = new Student;delete pt;

运行结果会出错。

反正是只要基类析构没有定义为virtual,而派生类(可能有多层)中有把析构定义为virtual的,此时用基类的指针指向派生类,再delete,会出错。

而:

class Person
{
public:
~Person()
{cout << "Person::~Person()" << endl;
}
};class Student : public Person
{
public:
virtual ~Student()
{cout << "Student::~Student()" << endl;
}
};class OneSt : public Student
{
public:
~OneSt()
{cout << "OneSt::~OneSt()" << endl;
}
};Student * pt = OneSt;  delete pt;

运行结果为:

OneSt::~OneSt()

Student::~Student()

Person::~Person()

是可以运行的。



Effective C++ (第7条:要将多态基类的析构函数声明为虚函数)

需要记住的
应该为多态基类声明虚析构器。一旦一个类包含虚函数,它就应该包含一个虚析构器。
如果一个类不用作基类或者不需具有多态性,便不应该为它声明虚析构器。

转处:http://www.cnblogs.com/AndyJee/p/4575810.html

转载于:https://www.cnblogs.com/laohaozi/p/8266550.html

析构函数定义为虚函数原因相关推荐

  1. 父类的析构函数定义为虚函数

  2. C++——虚函数、虚析构函数、纯虚函数、抽象类

    目录 一.虚函数 1.什么是虚函数? 2.虚函数的作用 3.虚函数的参数 4.虚函数代码示例 二.虚析构函数 1.什么是虚析构函数? 2.虚析构函数的作用 3. 构造函数 4.为什么构造函数不能是虚函 ...

  3. 构造函数为什么一般不定义为虚函数?而析构函数一般写成虚函数的原因 ?

    1.构造函数不能声明为虚函数 1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的.而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等 ...

  4. 构造函数不可以是虚函数;析构函数可以是虚函数,也可以是纯虚函数。

    构造函数不可以是虚函数:析构函数可以是虚函数,也可以是纯虚函数. 一:构造函数不能声明为虚函数的原因 1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的. 而在构造 ...

  5. 【c++】28.虚析构函数、纯虚函数

    1.虚函数:在类的成员函数前面加virtual关键字的函数: 一般把虚函数定义在public区,方便在主函数中调用 如果一个类有一个虚函数,则该类就有一个虚函数列表,所有该类的对象都共享这个虚函数表: ...

  6. C/Cpp / C++ 构造函数和析构函数可以是虚函数吗

    答案 构造函数不可以是虚函数,而析构函数可以且常常是虚函数. 原因 1.构造函数不可以是虚函数 当类中声明虚函数时,编译器会在类中生成一个虚函数表,虚函数表是一个存储成员函数指针的数据结构. 虚函数表 ...

  7. 不要在构造和析构函数中使用虚函数

    前言 本文将讲解一个新手 C++ 程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实 ...

  8. C++核心准则C.82:不要在构造函数或析构函数中调用虚函数

    C.82: Don't call virtual functions in constructors and destructors C.82:不要在构造函数或析构函数中调用虚函数 Reason(原因 ...

  9. C++中最好不要在构造函数和析构函数中调用虚函数!!!

    1.最好不要在基类和派生类的构造和析构函数中调用虚函数,不会出现多态性 实例如下: #include "iostream"using namespace std;class Bas ...

  10. C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配

    一.构造函数和析构函数中对虚函数的调用 仍然以https://blog.csdn.net/Master_Cui/article/details/109957302中的代码为例 base3构造函数和析构 ...

最新文章

  1. 对文本框只允许输入数字
  2. Android布局整合include界面控件 示例
  3. 深度学习:反向传播(back-propagation)
  4. leetcode 129. 求根到叶子节点数字之和(先序遍历)
  5. java的核心类库_Java核心类库,集合框架
  6. isis network-entity 49含义_电影《狮子王》真人版上映,经典英语台词背后的含义你看懂了吗...
  7. Golang原生sql操作Mysql数据库增删改查
  8. 微软:免费杀毒软件Morro即将发布Beta版
  9. matlab中ifelse能嵌套吗,MATLAB嵌套if-else语句
  10. 烟雨要饭网最终版源码
  11. 火星坐标系(GCJ-02坐标系),CGCS2000坐标系,WGS-84坐标系
  12. 小技巧——网页下载提速
  13. linux鼠标晃动出现,鼠标指针抖动的原因及其解决方法【详解】
  14. ALLHIC使用 | HiC辅助基因组组装(三)
  15. 百度网盘网页版增加倍速播放速度
  16. 高效的公式提取神器Mathpix snipping Tool+ Mathtype
  17. Apache Commons-pool2使用入门
  18. error:src refspec xxx does not match any的原因及解决办法
  19. 树莓派远程视频监控的移植pistreaming
  20. shift键计算机功能,shift键的功能

热门文章

  1. this指针常识性问题
  2. boost库BOOST_FOREACH使用说明
  3. 您不是订单管理的定向开发者_全面升级投放和营销能力 华为应用市场商业推广助力开发者高效增长...
  4. MacOS 迅速上手 Makefile 编译 C / C++ 工程
  5. msf拿shell后中文乱码解决
  6. 能力提升综合题单 Part 8.4 生成树Part 8.5 拓扑排序Part 8.6 差分约束
  7. 153.寻找旋转排序数组中的最小值(力扣leetcode) 博主可答疑该问题
  8. c语言上机作业题及答案,华为C语言上机试题及答案
  9. 第 7 章 Neutron - 067 - Neutron 架构
  10. spring4.1.8扩展实战之七:控制bean(BeanPostProcessor接口)