主要内容:

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/AndyJee/p/4575810.html

(C++)浅谈多态基类析构函数声明为虚函数相关推荐

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

    原博文:https://www.cnblogs.com/AndyJee/p/4575810.html 主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.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++基类的析构函数为何要声明为虚函数

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

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

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

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

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

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

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

最新文章

  1. matlab 极坐标作图polar
  2. 【2】青龙面板入门系列教程之宝塔面板的安装以及docker的安装
  3. pl/sql链接64位oracle数据库报错Could not initialize oci.dll
  4. Boost:双图bimap与mi_hashed indices索引的测试程序
  5. Ribbon自带负载均衡策略比较
  6. Abp Uow 设计
  7. IntelliJ IDEA Community社区版集成Tomcat or Jetty教程
  8. ubuntu18.04安裝搜狗輸入法
  9. Java连接MySQL8.0以上版本数据库方式
  10. 系统业务逻辑书籍_新年福利 | 架构的“一小步”,业务的一大步
  11. Fiddler添加过滤条件
  12. (转)在NGUI使用图片文字(数字、美术字)(直接可用于UILable)
  13. Office转换pdf(oppenOffice和jacob两种)
  14. 按下组合键 可以迅速锁定计算机,电脑快速锁屏快捷键
  15. GTS、GCK,GSR全称
  16. 用 visual foxpro 也可以编写“迅雷下载”
  17. 华为交换机配置接口安全
  18. 计算机怎么查看网络连接的地址,各种电脑系统如何查看连接路由器的登录地址是多少?...
  19. PHP画a梦,使用canvas画“哆啦A梦”时钟的代码
  20. LearnOpenGL学习笔记——几何着色器

热门文章

  1. linux lsof
  2. werkzeug routing.Rule
  3. MySQL Window Function Descriptions
  4. MySQl Window Function Concepts
  5. Java Servlet ServletContext
  6. 3.8 激活函数的导数
  7. 归纳推理测试没做完_天气热,教你用寒天粉做果冻,清凉爽滑,5秒吃完一盘没问题...
  8. 高速通道 > 专有网络对等连接(关闭新购) > VPC互连
  9. 2020年中国网络安全市场全景图
  10. 3种更新vCenter Server Appliance 6.5的方法