主要内容:

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. The dd command of linux

    The dd command stands for "data duplicator" and used for copying and converting data. It i ...

  2. 【贪心】BZOJ3668-[NOI2014]起床困难综合症

    [题目大意] 给定n次操作(与,或,异或),在0~m中选择一个数,使这个数经过n次操作后得到的值最大. [思路] 水题orz 枚举这个数每一位的取值是0还是1,然后根据它经过n次操作后的结果判断: ( ...

  3. 【树上主席树】BZOJ2588-Count on a tree

    [题目大意] 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第 ...

  4. Colorful Lecture Note

    Colorful Lecture Note 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi is writing an algorithm lectu ...

  5. Cwrsync_rsync windows_windows下的rsync

    1.官网已不允许免费下载cwrsync的server了,我就先给出下载地址: http://files.cnblogs.com/files/assassin1994/cwRsync_4.0.5_ser ...

  6. mysql配置文件my.ini优化详解

    mysql 5.5.13参数说明:[client]character-set-server = utf8port = 3306socket = /data/mysql/3306/mysql.sock[ ...

  7. jquery-问题解答

    1.var v = $('.summer-input:input').val(); //依据class获取input 2.var v = $('input[name=user\\.name]').va ...

  8. OpenERP实施记录(14):收款处理

    本文是<OpenERP实施记录>系列文章的一部分. 1. 在前面的文章中,销售订单确认时自动生成了客户发票,可以在 会计 > 客户 > 客户发票 查询,状态为"草稿& ...

  9. appium+python自动化58-xpath定位

    基本属性定位 以淘宝app为例,定位左上角扫一扫按钮 1.可以通过text文本定位到 //*[@text='text文本属性'] # 定位text driver.find_element_by_xpa ...

  10. POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写

    再读本篇文章之前,请先看我的前一篇文章,前一篇文章中有重点讲到POI设置EXCEL单元格格式为文本格式,剩下的设置小数.百分比.货币.日期.科学计数法和中文大写这些将在下面一一写出 以下将要介绍的每一 ...