Virtual Destructor
Deleting a derived class object using a pointer to a base class that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor.
Source: https://www.securecoding.cert.org/confluence/display/cplusplus/OOP34-CPP.+Ensure+the+proper+destructor+is+called+for+polymorphic+objects
For example, following program results in undefined behavior. Although the output of following program may be different on different compilers, when compiled using Dev-CPP, it prints following.
Constructing base
Constructing derived
Destructing base
1 // A program without virtual destructor causing undefined behavior
2 #include<iostream>
3
4 using namespace std;
5
6 class base
7 {
8 public:
9 base()
10 {
11 cout<<"Constructing base \n";
12 }
13 ~base()
14 {
15 cout<<"Destructing base \n";
16 }
17 };
18
19 class derived: public base
20 {
21 public:
22 derived()
23 {
24 cout<<"Constructing derived \n";
25 }
26 ~derived()
27 {
28 cout<<"Destructing derived \n";
29 }
30 };
31
32 int main(void)
33 {
34 derived *d = new derived();
35 base *b = d;
36 delete b;
37 getchar();
38 return 0;
39 }
Making base class destructor virtual guarantees that the object of derived class is destructed properly, i.e., both base class and derived class destructors are called.
For example, following program prints:
Constructing base
Constructing derived
Destructing derived
Destructing base
1 // A program without virtual destructor causing undefined behavior
2 #include<iostream>
3
4 using namespace std;
5
6 class base
7 {
8 public:
9 base()
10 {
11 cout<<"Constructing base \n";
12 }
13 virtual ~base()
14 {
15 cout<<"Destructing base \n";
16 }
17 };
18
19 class derived: public base
20 {
21 public:
22 derived()
23 {
24 cout<<"Constructing derived \n";
25 }
26 ~derived()
27 {
28 cout<<"Destructing derived \n";
29 }
30 };
31
32 int main(void)
33 {
34 derived *d = new derived();
35 base *b = d;
36 delete b;
37 getchar();
38 return 0;
39 }
As a guideline, any time you have a virtual function in a class, you should immediately add a virtual destructor (even if it does nothing). This way, you ensure against any surprises later.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
转载请注明:http://www.cnblogs.com/iloveyouforever/
2013-11-26 21:06:36
Virtual Destructor的更多相关文章
- [C++] Virtual Destructor(虚析构函数)
Without Virtual Destructor(虚析构函数) class A{ public: ; A() { cout <<"A()..."<< e ...
- [CareerCup] 13.6 Virtual Destructor 虚析构函数
13.6 Why does a destructor in base class need to be declared virtual? 这道题问我们为啥基类中的析构函数要定义为虚函数.首先来看下面 ...
- effective c++ 条款7 declare virtual destructor for polymophyc base class
这似乎很明显. 如果base class的destructor不是virtual,当其derived class作为基类使用,析构的时候derived class的数据成员将不会被销毁. 举个例子 我 ...
- C++ 虚析构(virtual destructor)原理
注意:本文仅为个人理解,可能有误! 先看一段代码: #include <iostream> using namespace std; class CBase{ public: CBase( ...
- 《Effective C++》条款14 总是让base class拥有virtual destructor
有时,一个类想跟踪它有多少个对象存在.一个简单的方法是创建一个静态类成员来统计对象的个数.这个成员被初始化为0,在构造函数里加1,析构函数里减1.(条款m26里说明了如何把这种方法封装起来以便很容易地 ...
- 为什么内联函数,构造函数,静态成员函数不能为virtual函数
http://blog.csdn.net/freeboy1015/article/details/7635012 为什么内联函数,构造函数,静态成员函数不能为virtual函数? 1> 内联函数 ...
- 条款7:为多态基类声明virtual析构函数
C++明确指出:当派生类对象是由一个基类指针释放的,而基类中的析构函数不是虚函数,那么结果是未定义的.其实我们执行时其结果就是:只调用最上层基类的析构函数,派生类及其中间基类的析构函数得不到调用. # ...
- Memory Layout for Multiple and Virtual Inheritance
Memory Layout for Multiple and Virtual Inheritance(By Edsko de Vries, January 2006)Warning. This art ...
- why pure virtual function has definition 为什么可以在基类中实现纯虚函数
看了会音频,无意搜到一个frameworks/base/include/utils/Flattenable.h : virtual ~Flattenable() = 0; 所以查了下“纯虚函数定义实现 ...
随机推荐
- Python批量爬取谷歌原图,2021年最新可用版
文章目录 前言 一.环境配置 1.安装selenium 2.使用正确的谷歌浏览器驱动 二.使用步骤 1.加载chromedriver.exe 2.设置是否开启可视化界面 3.输入关键词.下载图片数.图 ...
- Unity Ioc 类型初始值设定项引发异常,The type name or alias SqlServer could not be resolved. Please check your configuration file and verify this type name.
先看一下unity的配置信息 <unity> <typeAliases> <typeAlias alias="IDatabase" type=&quo ...
- [noi712]练级
先考虑一个联通块,可以发现这个联通快内不会存在两个偶数的点证明:如果存在,那么这两个点的某一条路径上的边全部反过来,可以使答案+2,即答案为点数或点数-1同时,发现答案的奇数点数一定与边数同奇偶,那么 ...
- [cf1421E]Swedish Heroes
令$p_{i}$为最终$a_{i}$之前的系数($p_{i}\in \{-1,1\}$),则有$n+\sum_{i=1}^{n}[p_{i}=-1]\equiv 1(mod\ 3)$ 证明:对于两个满 ...
- 微信小程序的优点(水一篇)
- 快速的加载 - 更强大的能力 - 原生的体验 - 易用且安全的微信数据开放 - 高效和简单的开发 摘自微信官方文档 https://developers.weixin.qq.com/minipro ...
- springboot默认Thymeleaf模板引擎js的解决方案
<script th:inline="javascript"> var btnexam=[[${btnexam}]]; console.log(btnexam); va ...
- 论文翻译:2021_Decoupling magnitude and phase optimization with a two-stage deep network
论文地址:两阶段深度网络的解耦幅度和相位优化 论文代码: 引用格式:Li A, Liu W, Luo X, et al. ICASSP 2021 deep noise suppression chal ...
- c# Quartzs定时器的简单使用
使用背景: 首先想到倒计时,定时任务.大家想到的肯定就是定时器.那么定时器在web和winfrom程序中有着很大的作用.那在服务器端有没有像定时器一样的存在呢. 有了这些需求,我找到了第三方的组件 Q ...
- 跟着老猫来搞GO,"面向对象"
前言 之前和大家分享了容器以及相关的基础语法,以及函数,相信如果大家有接触过C++或者java的朋友都晓得面向对象,其实在GO语言中也存在面向对象,但是还是比较简单的,下面我们来看一下GO语言的&qu ...
- Codeforces Gym 101221G Metal Processing Plant(2-SAT)
题目链接 题意:有 \(n\) 个元素,第 \(i\) 个数与第 \(j\) 个数之间有一个权值 \(d_{i,j}\),\(d(i,j)=d(j,i)\). 定义函数 \(D(S)=\max\lim ...