本文主要是介绍C++派生类的初始化顺序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在C++中,派生类的初始化顺序遵循以下规则:
-
基类构造函数:首先,按照基类在派生类中的声明顺序,从基类到基类依次调用它们的构造函数。如果派生类有多个基类(即多重继承),则按照派生类定义中基类的声明顺序来调用基类的构造函数。
-
成员变量构造函数:在基类的构造函数调用之后,派生类的成员变量按照它们在派生类定义中的声明顺序进行初始化。这包括所有的数据成员,无论它们是基本类型还是其他类的对象。
-
派生类构造函数体:在所有基类和成员变量的构造函数调用完成之后,执行派生类构造函数的函数体。
下面是一个简单的例子来说明这个顺序:
#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
类有两个基类 Base1
和 Base2
,以及一个成员变量 m
的类型为 Member
。按照规则,首先按照基类在派生类中的声明顺序调用 Base1
和 Base2
的构造函数,然后按照成员变量在派生类中的声明顺序调用 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++派生类的初始化顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!