c++基类对象和成员对象的初始化顺序

 

#include <iostream>
using namespace std;
class B1 // 基类B1,构造函数有参数
{
public:
	B1(int i) { cout << "constructing B1 " << i << endl; }
};
class B2 // 基类B2,构造函数有参数
{
public:
	B2(int j) { cout << "constructing B2 " << j << endl; }
};
class B3 // 基类B3,构造函数无参数
{
public:
	B3() { cout << "constructing B3 *" << endl; }
};
class C : public B2, public B1, public B3
{
public: // 派生类的公有成员
	C(int a, int b, int c, int d) : B1(a), memberB2(d), memberB1(c), B2(b) {}

private: // 派生类的私有对象成员
	B1 memberB1;
	B2 memberB2;
	B3 memberB3;
};
void main()
{
	C obj(1, 2, 3, 4);
}

 

这段代码中的构造函数部分:

C(int a, int b, int c, int d) : B1(a), memberB2(d), memberB1(c), B2(b) {}

这是C++的构造函数初始化列表(Constructor Initialization List)语法。

语法解释:

基本格式:

构造函数名(参数列表) : 成员1(初始值), 成员2(初始值), ... {}

在这个例子中:

  • C(int a, int b, int c, int d) - 派生类C的构造函数,接收4个参数
  • : - 初始化列表开始标志
  • B1(a) - 用参数a(值为1)调用基类B1的构造函数
  • memberB2(d) - 用参数d(值为4)初始化成员对象memberB2
  • memberB1(c) - 用参数c(值为3)初始化成员对象memberB1
  • B2(b) - 用参数b(值为2)调用基类B2的构造函数
  • {} - 构造函数体(这里是空的)

实际执行顺序:

重要:虽然初始化列表中的顺序是 B1(a), memberB2(d), memberB1(c), B2(b),但实际的构造顺序遵循固定规则:

  1. 基类构造:按继承声明顺序

    class C : public B2, public B1, public B3  // 声明顺序
    • B2(2) 先构造
    • B1(1) 后构造
    • B3() 最后构造(无参构造函数,自动调用)
  2. 成员对象构造:按成员声明顺序

    private:
        B1 memberB1;  // 先声明
        B2 memberB2;  // 后声明
        B3 memberB3;  // 最后声明
    • memberB1(3) 先构造
    • memberB2(4) 后构造
    • memberB3() 最后构造(默认构造)

完整的输出结果:

constructing B2 2
constructing B1 1  
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *

为什么使用初始化列表?

  1. 必须使用的情况

    • 基类没有默认构造函数
    • 成员对象没有默认构造函数
    • const成员变量
    • 引用成员变量
  2. 性能优势

    • 直接初始化,避免先默认构造再赋值
    • 更高效

这种设计确保了派生类能够正确地初始化其基类和成员对象。

 

posted @ 2025-06-12 15:01  ChuckLu  阅读(34)  评论(0)    收藏  举报