当前位置: 首页 > news >正文

C++ 详谈继承体系下的构造函数和析构函数

前言

前面呢, 我们说了C++中实现多态的原理, 其中也说了, 虚函数表和虚函数指针的创建时机, C++ 详谈多态实现原理-CSDN博客 , 这一节呢, 我们会说说在C++中继承体系下的另一个知识点, 那就是: 继承体系下的构造函数和析构函数~~, 主要围绕两个问题: 执行顺序? 虚析构函数的作用? 

继承体系下的构造函数和析构函数的执行顺序

首先我们用一句话来概括, 之后再做详细解释: 继承下, 构造函数按照依赖链(孩子依赖父亲), 从上往下构造, 析构函数按照依赖链, 从下向上析构.

我们从两个角度来探讨, 单继承 和 多继承.

单继承

我们现在在前面代码的基础上添加两个类, Base1和Drive1, Base1作为Base类中的成员变量, Drive1作为Drive中的成员变量, 我们可以设想一些这个情况下的调用顺序, 构造Drive之前要先构造Base 和 构造Drive1, 构造Base之前要先构造Base1, 所以其构造顺序应该是: Base1, Base, Drive1, Drive, 其析构顺序应该是: Drive, Drive1, Base, Base1

#include <iostream>using namespace std;class Base1
{
public:Base1(){cout << "Base1 construction" << endl;}~Base1(){cout << "Base1 destruction" << endl;}
};
class Drive1
{
public:Drive1(){cout << "Drive1 construction" << endl;}~Drive1(){cout << "Drive1 destruction" << endl;}
};
class Base
{
public:Base(){cout << "Base construction" << endl;}~Base(){cout << "Base destruction" << endl;}
private:Base1 b1;
};
class Drive : public Base
{
public:Drive(){cout << "Drive construction" << endl;}~Drive(){cout << "Drive destruction" << endl;}
private:Drive1 d1;
};
int main()
{Drive d;cout << "------------------" << endl;return 0;
}

成员类按照顺序构造, 优先于类的构造, 按照相反顺序析构. 

多继承

现在, 代码有 一个MBase1和MBase2, 一个MDrive多继承自MBase1和MBase2, 并且MDrive中还有成员变量, MDrive1和MDrive2类型的变量, 构造顺序是继承的顺序

#include <iostream>using namespace std;class MBase1
{
public:MBase1(){cout << "MBase1 construction" << endl;}~MBase(){cout << "MBase1 destruction" << endl;}
};
class MBase2
{
public:MBase2(){cout << "MBase2 construction" << endl;}~MBase2(){cout << "MBase2 destruction" << endl;}
};
class MDrive1
{
public:MDrive1(){cout << "MDrive1construction" << endl;}~MDrive1(){cout << "MDrive1destruction" << endl;}
};
class MDrive2
{
public:MDrive2(){cout << "MDrive2 construction" << endl;}~MBase(){cout << "MDrive2 destruction" << endl;}
};
class MDrive : public MBase1, MBase2
{
public:MDrive(){cout << "MDrive construction" << endl;}~MDrive(){cout << "MDrive destruction" << endl;}
private:MDrive1 md1;MDrive2 md2;
};
int main()
{MDrive md;cout << "------------------" << endl;return 0;
}

多继承中, 除了前面单继承中的构造顺序, 基类是声明顺序构造, 相反顺序析构, 上面这一段代码就是, 先构造MBase1, 再构造MBase2, 再构造MDrive1和MDirve2, 最后构造MDrive.

虚析构函数的作用

作用: 在继承下, 为了使子类析构函数能够得到正常调用, 需要将基类的析构函数设置为虚析构函数.

 C++中, 当一个类要被作为基类被继承是, 应该将这个基类的析构函数手动设置为虚析构函数, 之前说过, C++中如果一个方法是virtual修饰的, 那么在子类继承之后重写这个方法, 也是virtual修饰的, C++会将所有的析构函数名称修改成同一个.

这样如果父类的析构函数是虚析构函数, 子类中一定是有同名的虚的析构函数, 这样经过两次vptr的赋值, 就能正常的调用到虚构造函数了~~

http://www.dtcms.com/a/288962.html

相关文章:

  • k8s:离线添加集群节点的相关组件安装与升级
  • GeoServer 信息泄漏漏洞复现(CVE-2025-27505)
  • 周志华《机器学习导论》第11章 特征选择与稀疏学习
  • 机器学习-数据预处理
  • 闲庭信步使用图像验证平台加速FPGA的开发:第二十六课——正弦波DDS的FPGA实现
  • leetcode75【经典动态规划】之:最长公共子序列
  • nginx源码解读-------整体架构
  • 30天打牢数模基础-LightGBM讲解
  • 网络地址和主机地址之间进行转换的类
  • springboot电影推荐网站—计算机毕业设计源码—30760
  • 在Ubutu22系统上面离线安装Go语言环境【教程】
  • 【开源项目】基于RuoYi-Vue-Plus的开源进销存管理系统
  • Spring之AOP面向切面编程详解
  • 软件工程学概述:从危机到系统化工程的演进之路
  • MySQL详解三
  • Java 字符集(Charset)详解:从编码基础到实战应用,彻底掌握字符处理核心机制
  • 文件编码概念|文件的读取操作|文件读取的课后练习讲解
  • 数据治理,治的是什么?
  • 0719代码调试记录
  • 【星海出品】python安装调试篇
  • 网络安全隔离技术解析:从网闸到光闸的进化之路
  • Spring Boot总结
  • RabbitMQ核心组件浅析:从Producer到Consumer
  • 深入理解设计模式:访问者模式详解
  • 深入理解浏览器解析机制和XSS向量编码
  • Java中List<int[]>()和List<int[]>[]的区别
  • React-Native开发环境配置-安装工具-创建项目教程
  • 数据并表技术全面指南:从基础JOIN到分布式数据融合
  • Pinia 核心知识详解:Vue3 新一代状态管理指南
  • 六边形滚动机器人cad【7张】三维图+设计书明说