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 ...
随机推荐
- JTabbedPane 和 JScrollBar 联合使用
需求:实现一个JTabbed, 当下拉到Tabbed的底部时,自动加载下一次的数据. 下面是具体代码: import java.awt.*; import javax.swing.table.Defa ...
- .NET LINQ 数据分组
数据分组 分组指将数据放入组中以便每个组中的元素共享公共特性的操作. 方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表达式语法 更多信息 GroupBy 对共享 ...
- 【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】
一.JavaScript基础增强 1.弹窗 (1)使用window对象的showModelDialog方法和showModelessDialog方法分别可以弹出模式窗口和非模式窗口,但是只能在IE中使 ...
- BlockingQueue使用
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import ja ...
- UWP 解决Webview在Pivot里面无法左右滑动的问题
//为了解决webview在PivotItem里面,阻止pivot左右滑动. if (webView != null) { rootGrid.Children.Remove(webView); web ...
- java中的权限修饰符的理解
首先了解概念: 在java中有四种权限修饰符:范围从大到小分别是:public.protect.default(friendly).private,它们之间的区别是: public: Java语言中访 ...
- (iOS)项目总结-项目中遇到的各种的问题和解决方法
前言: 一到公司报道那时,便着手独立的去完成了一个项目,其中的辛酸泪也是不足为外人道也.这次算是一个新型的app,仍然是独立开发,但心境和想法却是完全的不同.下面说一次以前做开发时常常忽略的知识,也算 ...
- Salt安装(yum不可用时)
salt-master安装 [salt-master]# yum install salt-master 或者 curl -L http://bootstrap.saltstack.o ...
- Leetcode Merge Intervals
Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6],[8,1 ...
- ZeroMQ接口函数之 :zmq_msg_send – 从一个socket发送一个消息帧
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_msg_send zmq_msg_send(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_ ...