C++派生类的初始化顺序

2024-04-11 15:36
文章标签 c++ 初始化 顺序 派生类

本文主要是介绍C++派生类的初始化顺序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在C++中,派生类的初始化顺序遵循以下规则:

  1. 基类构造函数:首先,按照基类在派生类中的声明顺序,从基类到基类依次调用它们的构造函数。如果派生类有多个基类(即多重继承),则按照派生类定义中基类的声明顺序来调用基类的构造函数。

  2. 成员变量构造函数:在基类的构造函数调用之后,派生类的成员变量按照它们在派生类定义中的声明顺序进行初始化。这包括所有的数据成员,无论它们是基本类型还是其他类的对象。

  3. 派生类构造函数体:在所有基类和成员变量的构造函数调用完成之后,执行派生类构造函数的函数体。

下面是一个简单的例子来说明这个顺序:

#include <iostream>class Base1 {
public:Base1() { std::cout << "Base1 constructor\n"; }
};class Base2 {
public:Base2() { std::cout << "Base2 constructor\n"; }
};class Member {
public:Member() { std::cout << "Member constructor\n"; }
};class Derived : public Base1, public Base2 {Member m;public:Derived() { std::cout << "Derived constructor\n"; }
};int main() {Derived d;return 0;
}

输出将是:

Base1 constructor // 基类Base1的构造函数
Base2 constructor // 基类Base2的构造函数
Member constructor // 成员变量m的构造函数
Derived constructor // 派生类Derived的构造函数体

在这个例子中,Derived 类有两个基类 Base1Base2,以及一个成员变量 m 的类型为 Member。按照规则,首先按照基类在派生类中的声明顺序调用 Base1Base2 的构造函数,然后按照成员变量在派生类中的声明顺序调用 Member 的构造函数,最后执行 Derived 类的构造函数体。

重要的是要注意,即使你在派生类的初始化列表中显式地指定了基类和成员变量的初始化顺序,实际的初始化顺序还是按照它们在派生类定义中的声明顺序来决定的。初始化列表只是用于提供初始化参数和可能的初始化表达式,它并不改变实际的初始化顺序。

接下来给出一道例题:

#include <iostream>
using namespace std;class A
{
protected:int x;public:A(int x) {this->x = x;cout << "A构造函数\n";}~A() {cout << "A析构函数\n";}
};
class B
{
protected:int y;public:B(int y) {this->y = y;cout << "B构造函数\n";}~B() {cout << "B析构函数\n";}
};class C:public A
{int z;B b;A a;public:C(int x, int y, int z) :A(x), a(x + y), b(y) {this->z = z;cout << "C构造函数\n";}~C(){cout << "c析构函数\n";}
};int main()
{C c(1,2,3);return 0;
}

上述代码的运行结果是:

A构造函数
B构造函数
A构造函数
C构造函数
c析构函数
A析构函数
B析构函数
A析构函数

这篇关于C++派生类的初始化顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/894481

相关文章

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提