转载:(C++)浅谈多态基类析构函数声明为虚函数
原博文:https://www.cnblogs.com/AndyJee/p/4575810.html
主要内容:
1、C++类继承中的构造函数和析构函数
2、C++多态性中的静态绑定和动态绑定
3、C++多态性中析构函数声明为虚函数
1、C++类继承中的构造函数和析构函数
在C++的类继承中,
建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推;
析构对象时,其顺序正好与构造相反;
具体参考文章:http://www.cnblogs.com/AndyJee/p/4575385.html
2、C++多态性中的静态绑定和动态绑定
对象的静态类型:对象在声明是采用的类型,在编译期确定;
对象的动态类型:当前对象所指的类型,在运行期决定,对象的动态类型可以更改,但静态类型无法更改。
静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。
具体参考文章:http://www.cnblogs.com/AndyJee/p/4575670.html
3、C++多态性中基类析构函数声明为虚函数
先来看几段程序例子:
- 将基类析构函数声明为虚函数
#include <iostream> using namespace std;class Person{ public:virtual ~Person(){ //declare destructor as a virtual functioncout << "Person::~Person()" << endl;} };class Student : public Person{ public:~Student(){ // virtual or not is OKcout << "Student::~Student()" << endl;} };int main(){Person *pt1 = new Person;Person *pt2 = new Student; // base class pointer point to derived class// Student *pt3 = new Person; // derived class pointer can not point to base classStudent *pt4 = new Student;delete pt1;cout << "*********" << endl;delete pt2;cout << "*********" << endl;//delete pt3;//cout << "*********" << endl;delete pt4;cout << "*********" << endl;return 0; }
、
- 不将基类析构函数声明为虚函数:
#include <iostream> using namespace std;class Person{ public:~Person(){ //declare destructor as a virtual functioncout << "Person::~Person()" << endl;} };class Student : public Person{ public:~Student(){ // virtual or not is OKcout << "Student::~Student()" << endl;} };int main(){Person *pt1 = new Person;Person *pt2 = new Student; // base class pointer point to derived class// Student *pt3 = new Person; // derived class pointer can not point to base classStudent *pt4 = new Student;delete pt1;cout << "*********" << endl;delete pt2;cout << "*********" << endl;//delete pt3;//cout << "*********" << endl;delete pt4;cout << "*********" << endl;return 0; }
可以看出:
在用基类指针指向派生类时,
在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数。
在基类析构函数没有声明为virtual的时候,delete基类指针,只会调用基类的析构函数,而不会调用派生类的析构函数,这样会造成销毁对象的不完全。
分析:
Person *pt2 = new Student;
pt2的静态类型为Person,而动态类型为Student,
当析构函数为虚函数时,为动态绑定,delete pt2,会调用动态类型即派生类的析构函数,由于继承关系,也会调用基类的析构函数;
而当析构函数为非虚函数时,为静态绑定,delete pt2,会调用静态类型即基类的析构函数,而不会调用派生类的析构函数。
(以上纯属个人理解)
总结:
应该为多态基类声明虚析构器。一旦一个类包含虚函数,它就应该包含一个虚析构器,因为多态性,必定会有基类调用派生类。
如果一个类不用作基类或者不需具有多态性,便不应该为它声明虚析构器。
参考文章:
http://www.cnblogs.com/children/archive/2012/08/13/2636956.html
转载于:https://www.cnblogs.com/strivingforever/p/8622339.html
转载:(C++)浅谈多态基类析构函数声明为虚函数相关推荐
- (C++)浅谈多态基类析构函数声明为虚函数
主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...
- 虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承
虚函数:虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数.是C++中多态性的一个重要体现,利用基类指针访问派生类中的成员 ...
- 基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?
如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥? class BaseCls { public: BaseCls() { printf("BaseCls()n" ...
- C++的虚基类,抽象类,虚函数,纯虚函数,virtual
虚基类 在说明其作用前先看一段代码 class A { public: int iValue; }; class B:public A { public: void bPrintf(){cout< ...
- 声明一个哺乳动物类Mammal,再由此派生出狗类Dog,二者都定义Speak()成员函数,基类中定义为虚函数,声明类Dog的一个对象,调用函数Speak()
#include <iostream.h> #include <string.h> class Mammal { protected: char name[10]; publ ...
- C++ day22 继承(二)基类指针数组通过虚方法实现智能的多态
继承一共有三种: 公有继承 私有继承 保护继承 文章目录 公有继承 基类和派生类的关系 is-a(用公有继承表示"是一种"的关系) has-a uses-a is-like-a i ...
- 析构函数声明无效_C++基类的析构函数为何要声明为虚函数
C++的类中,构造函数用于初始化对象及相关操作,构造函数是不能声明为虚函数的,因为在执行构造函数前对象尚未完成创建,虚函数表还不存在. 析构函数用于销毁对象完成时相应资源的释放工作,析构函数可以被声明 ...
- 多态基类与虚析构函数
假设我们有一个基类A,很不幸的,A的析构函数是一个non-virtual.同时我们有一个派生类B,它派生自A. 我们定义了一个A类型指针,它指向的实际对象是B: A * ptr = new B; 然后 ...
- 为什么基类的析构函数要声明成虚函数
记得以后基类(父类) 的析构函数最好是声明为 虚函数 即:virtual 开发中遇到了一个比较傻逼的bug,也证明了理论与实际之间的差距. 在基类中没有声明其析构函数为虚函数,导致delete 释放操 ...
最新文章
- 批归一化和Dropout不能共存?这篇研究说可以
- Go语言从入门到精通 -【web项目实战篇】- Json详解
- Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 栈 链表
- 十三、StringBuffer
- Crfe php,新版中国菜刀(20141213)一句话不支持php assert分析
- CentOS 7配置静态IP地址 解决了IP失效问题
- python enumerate函数_关于python中enumerate和zip函数的用法及举例
- MySQL 数据库导出导入操作
- 记模拟面试日记(更新...)
- select不能触发change_SQL之警觉触发
- 通过SQL Server 2008数据库复制实现数据库同步备份
- stm32最小系统板原理图_嵌入式单片机之STM32F103C8T6最小系统板电路设计参考
- webGIS的粗浅认识(一)
- Pr学习笔记——添加字幕流
- 2022年国内各安卓应用市场上传教程
- 用GEOquery从GEO数据库下载数据
- URI跳转方式地图导航的代码实践
- win10系统一键安装教程
- 【用Unity实现抛物线向目标点发射炮弹功能】
- java简单的音乐播放器编程_简单实现java音乐播放器
热门文章
- 有关Visual Studio Code的说明
- MongoDB中的分页–如何真正避免性能下降?
- JUST——简单转换下的JSON
- hibernate整合mysql配置文件_springboot整合hibernate配置
- 晶体封装越小esr越大_晶振
- ie浏览器样式兼容写法_IE浏览器兼容问题-----html和css的兼容写法
- macos模拟器_苹果芯补完计划,iOS终将回归mac OS?
- Spring boot 项目目录结构
- c语言 存储,c语言存储类
- 防盗链python_python一行代码,实现网页视频下载