C++基类的析构函数定义为虚函数的原因
1:每个析构函数只会清理自己的成员(成员函数前没有virtual)。
2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类的析构函数要定义为虚函数;
基类指针可以指向派生类的对象(多态),如果删除该指针delete[]p,就会调用该指针指向的派生类的析构函数,而派生类的对象又会自动调基类的成员函数,这样就会把派生类的对象释放,如果基类的析构函数没有定义成虚函数,则编译器实现的静态绑定,在删除基类的指针,只会释放基类的析构函数而不会释放派生类的成员函数,此时会导致释放内存不完全,就会导致内存泄露的问题。
一:派生类指针指向派生类的对象
class Base
{
public: Base()
{ cout << "Base()" << endl; }
virtual ~Base()
{
cout << "~Base()" << endl;
}
};
class Driver :public Base
{
public: Driver()
{
cout << "Driver()" << endl;
}
~Driver()
{
cout << "~Driver()" << endl;
}
};
void Test()
{
Driver*pd = new Driver;
delete pd;
}
结果:
base()
Driver()
~Driver()
~Base()
派生的指针指向派生类的对象,释放p的过称是先释放派生类的析构函数,再释放基类的析构函数
二:基类的指针指向派生类的对象(无virtual)
class Base
{ public: Base()
{
cout << "Base()" << endl;
}
~Base()
{
cout << "~Base()" << endl;
}
}; class Driver :public Base
{ public: Driver()
{
cout << "Driver()" << endl;
}
~Driver()
{
cout << "~Driver()" << endl;
}
};
void Test()
{
Base *pd = new Driver;
delete pd;
}
运行结果:
Base()
Driver()
~Basce()
当基类的指针指向派生类的对象的成员,释放pd的过程是:只是释放了基类的资源,而没有调用派生类的析构函数;这样的删除只能删除基类对象,而不能删除派生类的对象,造成内存泄露;
在公有继承中,基类对派生类的对象的操作,只能影响哪些继承的成员,如果想要基类对非继承进行操作,则要把这个基类函数定义为虚函数;
C++基类的析构函数定义为虚函数的原因的更多相关文章
- C++中为什么要将析构函数定义成虚函数
构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个 ...
- 【转载】 C++多继承中重写不同基类中相同原型的虚函数
本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...
- 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...
- C++析构函数定义为虚函数(转载)
转载:http://blog.csdn.net/alane1986/article/details/6902233 析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函 ...
- C++多态性中基类析构函数声明为虚函数
在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...
- 构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数
一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数 ...
- 【C++】C++中基类的析构函数为什么要用virtual虚析构函数?
正面回答: 当基类的析构函数不是虚函数,并且基类指针指向一个派生类对象,然后通过基类指针来删除这个派生类对象时,如果基类的析构函数不是虚析构函数,那么派生类的析构函数就不会被调用,从而产生内存泄漏 # ...
- C++构造与析构函数中调用虚函数的问题
前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...
- C++中基类的析构函数为什么要用virtual虚析构函数
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
随机推荐
- 递归函数获得n个不重复的随机数
// 递归函数获取不重复的随机数 var arr_end; // 用于保存最后得到的数组 function suiji(n) { var arr = [] // 产生n个随机数加入数组 for(var ...
- 【读书笔记】iOS-方法声明
编译的时候 ,编译器会把方法前面的IBAction替换成void,把属性前面的IBOutlet移除掉,因为这些都 只是Interface Builder的标志而已.这个IBAction方法会被UI控件 ...
- python之线程相关操作(补充)
1 线程的其他方法 import threading import time from threading import Thread, current_thread def f1(n): time. ...
- vue-cli脚手架之webpack.dev.conf.js
webpack.dev.conf.js 开发环境模式配置文件: 'use strict'//js按照严格模式执行 const utils = require('./utils')//导入utils. ...
- Linux 学习笔记之超详细基础linux命令 Part 6
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 5----------------- ...
- python txt文件数据转excel
txt content: perf.txt 2018-11-12 16:48:58 time: 16:48:58 load average: 0.62, 0.54, 0.56 mosquitto CP ...
- 关于web优化(一)
我们所说的web,无非就是html,css(web font, image),JavaScript. HTML优化建议: 1. 尽量不要用table进行布局. 2. 尽量用最新的带有语义的h5标签,这 ...
- [软件逆向]实战Mac系统下的软件分析+Mac QQ和微信的防撤回
0x00 一点废话 最近因为Mac软件收费的比较多,所以买了几款正版软件,但是有的软件卖的有点贵,买了感觉不值,不买吧,又觉得不方便,用别人的吧,又怕不安全.于是我就买了正版的Hopper Di ...
- Excel两列查找重复值
判断A列的值在B列是否存在,如果存在则输出“yes” 在C1单元格使用如下公式: =IF(COUNTIF(A:A,B2)>0,"yes","")
- 02LaTeX学习系列之---TeX环境的搭建
目录 02Latex的下载与安装及其编译IDE 目录 前言 (一)Tex Live的下载 1. Tex Live官方下载网站: (二)TeXStudio 1.TeXStudio官网下载 2.TeXSt ...