原博文: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++)浅谈多态基类析构函数声明为虚函数相关推荐

  1. (C++)浅谈多态基类析构函数声明为虚函数

    主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...

  2. 虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承

    虚函数:虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数.是C++中多态性的一个重要体现,利用基类指针访问派生类中的成员             ...

  3. 基类的析构函数不能被继承。_为什么要把C++类中的析构函数声明为虚函数?

    如题,当一个类为基类的时候,通常其析构函数被声明为虚函数,这是为啥? class BaseCls { public: BaseCls() { printf("BaseCls()n" ...

  4. C++的虚基类,抽象类,虚函数,纯虚函数,virtual

    虚基类 在说明其作用前先看一段代码 class A { public: int iValue; }; class B:public A { public: void bPrintf(){cout< ...

  5. 声明一个哺乳动物类Mammal,再由此派生出狗类Dog,二者都定义Speak()成员函数,基类中定义为虚函数,声明类Dog的一个对象,调用函数Speak()

    #include <iostream.h> #include <string.h> class Mammal { protected:  char name[10]; publ ...

  6. C++ day22 继承(二)基类指针数组通过虚方法实现智能的多态

    继承一共有三种: 公有继承 私有继承 保护继承 文章目录 公有继承 基类和派生类的关系 is-a(用公有继承表示"是一种"的关系) has-a uses-a is-like-a i ...

  7. 析构函数声明无效_C++基类的析构函数为何要声明为虚函数

    C++的类中,构造函数用于初始化对象及相关操作,构造函数是不能声明为虚函数的,因为在执行构造函数前对象尚未完成创建,虚函数表还不存在. 析构函数用于销毁对象完成时相应资源的释放工作,析构函数可以被声明 ...

  8. 多态基类与虚析构函数

    假设我们有一个基类A,很不幸的,A的析构函数是一个non-virtual.同时我们有一个派生类B,它派生自A. 我们定义了一个A类型指针,它指向的实际对象是B: A * ptr = new B; 然后 ...

  9. 为什么基类的析构函数要声明成虚函数

    记得以后基类(父类) 的析构函数最好是声明为 虚函数 即:virtual 开发中遇到了一个比较傻逼的bug,也证明了理论与实际之间的差距. 在基类中没有声明其析构函数为虚函数,导致delete 释放操 ...

最新文章

  1. 批归一化和Dropout不能共存?这篇研究说可以
  2. Go语言从入门到精通 -【web项目实战篇】- Json详解
  3. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 栈 链表
  4. 十三、StringBuffer
  5. Crfe php,新版中国菜刀(20141213)一句话不支持php assert分析
  6. CentOS 7配置静态IP地址 解决了IP失效问题
  7. python enumerate函数_关于python中enumerate和zip函数的用法及举例
  8. MySQL 数据库导出导入操作
  9. 记模拟面试日记(更新...)
  10. select不能触发change_SQL之警觉触发
  11. 通过SQL Server 2008数据库复制实现数据库同步备份
  12. stm32最小系统板原理图_嵌入式单片机之STM32F103C8T6最小系统板电路设计参考
  13. webGIS的粗浅认识(一)
  14. Pr学习笔记——添加字幕流
  15. 2022年国内各安卓应用市场上传教程
  16. 用GEOquery从GEO数据库下载数据
  17. URI跳转方式地图导航的代码实践
  18. win10系统一键安装教程
  19. 【用Unity实现抛物线向目标点发射炮弹功能】
  20. java简单的音乐播放器编程_简单实现java音乐播放器

热门文章

  1. 有关Visual Studio Code的说明
  2. MongoDB中的分页–如何真正避免性能下降?
  3. JUST——简单转换下的JSON
  4. hibernate整合mysql配置文件_springboot整合hibernate配置
  5. 晶体封装越小esr越大_晶振
  6. ie浏览器样式兼容写法_IE浏览器兼容问题-----html和css的兼容写法
  7. macos模拟器_苹果芯补完计划,iOS终将回归mac OS?
  8. Spring boot 项目目录结构
  9. c语言 存储,c语言存储类
  10. 防盗链python_python一行代码,实现网页视频下载