主要内容:

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 function
cout << "Person::~Person()" << endl;
}
}; class Student : public Person{
public:
~Student(){ // virtual or not is OK
cout << "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 class
Student *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 function
cout << "Person::~Person()" << endl;
}
}; class Student : public Person{
public:
~Student(){ // virtual or not is OK
cout << "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 class
Student *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

(C++)浅谈多态基类析构函数声明为虚函数的更多相关文章

  1. C++多态性中基类析构函数声明为虚函数

    在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...

  2. 条款7:为多态基类析构函数声明为virtual

    基类指针指向子类对象. 子类对象必须位于堆.因此为了避免泄漏内存资源,当指针不使用时,delete掉每一个对象非常重要.但是如果基类的析构函数不声明为virtual.那么指向子类对象的指针delete ...

  3. why pure virtual function has definition 为什么可以在基类中实现纯虚函数

    看了会音频,无意搜到一个frameworks/base/include/utils/Flattenable.h : virtual ~Flattenable() = 0; 所以查了下“纯虚函数定义实现 ...

  4. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

  5. c++ 子类,基类 中this指针 虚函数使用

    笔记: 子类和基类 构造函数不显式时,的this指针相同..在QT中,如果父类基于QObject,那么构造子类时传入this指针,这样所有子类,父类,基类都是同一地址.delelater(),会del ...

  6. 抽象基类(ABC),纯虚函数

    #ifndef _ACCTABC_H_ #define _ACCTABC_H_ //(* #include <iostream> #include <string> //*) ...

  7. 条款7:为多态基类声明virtual析构函数

    C++明确指出:当派生类对象是由一个基类指针释放的,而基类中的析构函数不是虚函数,那么结果是未定义的.其实我们执行时其结果就是:只调用最上层基类的析构函数,派生类及其中间基类的析构函数得不到调用. # ...

  8. 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数

    1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...

  9. 从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数

    一.纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 在基类中不能给出有意义 ...

随机推荐

  1. 【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)

    4035: [HAOI2015]数组游戏 Time Limit: 15 Sec  Memory Limit: 32 MBSubmit: 181  Solved: 89 Description 有一个长 ...

  2. 【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 667  Solved: 350 Description 有一 ...

  3. 【BZOJ 2460】线性基

    2460: [BeiJing2011]元素 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力 ...

  4. 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机

    为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...

  5. const和define在值定义上的区别

    (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...

  6. ACM -- 算法小结(八)字符串算法之Manacher算法

    字符串算法 -- Manacher算法 首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅. //首先:大家都知道什么叫回文串吧,这个算法 ...

  7. MySQL之thread cache

    最近突然对MySQL的连接非常感兴趣,从status根据thread关键字可以查出如下是个状态 show global status like 'thread%'; +---------------- ...

  8. 在iOS 7中使用storyboard(part 1)

    原文:Storyboards Tutorial in iOS 7: Part 1        感谢翻译小组成员heartasice热心翻译.如果您有不错的原创或译文,欢迎提交给我们,更欢迎其他朋友加 ...

  9. 解决WPF中重载Window.OnRender函数失效问题

    今天实验一个绘图算法的时候,偶然发现重载Window.OnRender的方法是没有效果的. public partial class MainWindow : Window { public Main ...

  10. SD卡 TF卡 接口引脚定义