C++中为什么要将析构函数定义成虚函数
构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个死循环。
可是析构函数却要定义成虚函数,这是为什么呢,写一个非常简单的例子来理解一下:
class AA {
public:
AA() {};
~AA() { fun2(); };
virtual void fun1() {
cout << "Base construct" << endl;
}
virtual void fun2() {
cout << "Base destruct" << endl;
}
}; class BB : public AA {
public:
BB() { fun1(); };
~BB() { fun2(); };
void fun1() {
cout << "Derive construct" << endl;
}
void fun2() {
cout << "Derive destruct" << endl;
}
}; int main()
{
for (int i = ; i < ; i++) {
//AA a;
BB b;
}
return ;
}
输出结果:
所以可以看出,派生类对象构造的时候先调用基类的构造函数再调用派生类的构造函数,析构的时候先调用派生类析构函数再调用基类析构函数。
其实这个很好理解,派生类的成员由两部分组成,一部分是从基类那里继承而来,一部分是自己定义的。那么在实例化对象的时候,首先利用基类构造函数去初始化从基类继承而来的成员,再用派生类构造函数初始化自己定义的部分。
同时,不止构造函数派生类只负责自己的那部分,析构函数也是,所以派生类的析构函数会只析构自己的那部分,这时候如果基类的析构函数不是虚函数,则不能调用基类的析构函数析构从基类继承来的那部分成员,所以就会出现只删一半的现象,造成内存泄漏。
所以析构函数要定义成虚函数。
C++中为什么要将析构函数定义成虚函数的更多相关文章
- C++基类的析构函数定义为虚函数的原因
1:每个析构函数只会清理自己的成员(成员函数前没有virtual).2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类 ...
- C++析构函数定义为虚函数(转载)
转载:http://blog.csdn.net/alane1986/article/details/6902233 析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函 ...
- C++多态性中基类析构函数声明为虚函数
在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...
- C++:构造函数和析构函数能否为虚函数
原文:http://blog.csdn.net/xhz1234/article/details/6510568 C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可 ...
- C++函数中那些不可以被声明为虚函数的函数
转自C++函数中那些不可以被声明为虚函数的函数 常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函 ...
- C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址
C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...
- (C++)浅谈多态基类析构函数声明为虚函数
主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...
- C++反汇编第二讲,反汇编中识别虚表指针,以及指向的虚函数地址
讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当然也可以看原博客链接: http://blog.csdn.net ...
随机推荐
- XCode4.5.6,iOS6.1下测试 判断当前设备,及其联网状态等; 关于设备插上后XCode检测不出的情况的说明
目录[-] 一.判断设备 二.判断网络连接状态 三.设备不显示的解决办法 一.判断设备 01 //设备名称 02 return [UIDevice currentDevice].name; 03 ...
- iOS开发UI篇—核心动画(关键帧动画)
转自:http://www.cnblogs.com/wendingding/p/3801330.html iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimatio ...
- 不用写Windows服务实现定时器功能(FluentScheduler )
MacBook Pro 只有四个 USB Type-C 接口是否错了? 一项新技术的诞生总会对已存在的事物造成冲击或影响,如果大家都害怕冲击与影响,那这个世界永远像现在不变就行了,大家都好好的,待在自 ...
- iframe无刷新跨域并获得返回值
参考:http://geeksun.iteye.com/blog/1070607 /** * iframe跨域提交大数据 * @param action 跨域地址 * @param arr [ {na ...
- 环境变量/path/classpath/JAVA_HOME/JAVA环境变量配置
环境变量 环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息.例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在 ...
- Socket 类通信例子-第24章
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- VS2008切换设计视图卡死 停止响应
最近VS2008出现一个问题,打开项目后很快就非常慢,特别是切换设计视图马上卡死,很久也反应不过来.网上找了几种办法,都不好使,有的说是office影响的,有的说要改注册表,都试了一下,还是没用.后来 ...
- Linux学习总结
1.软链接和硬链接 ln 命令可用来创建硬链接或是符号链接.它的使用方式有两种. ln file link 用来创建硬链接 ln -s item link 用来创建符号链接,这里的item可以是文件也 ...
- hibernate的@EmbeddedId嵌入式主键详解
一.前言 在我们的日常开发中,有时候会用到数据库进行设计的时候,采用了复合主键来来保证唯一性,下面介绍一下采用hibernate的@EmbeddedId嵌入式主键. 二.说明 设计一个学生类,包含了三 ...
- Softmax回归
Reference: http://ufldl.stanford.edu/wiki/index.php/Softmax_regression http://deeplearning.net/tutor ...