C++ 中,成员初始化列表(Member Initializer List) 是构造函数的一种写法,用于在构造对象时初始化类成员变量。初始化顺序由成员变量在类中声明的顺序决定,而不是初始化列表的顺序。复杂对象(如自定义类成员)建议始终用成员初始化列表来构造。

1、类成员初始化

C++ 中,构造函数可以通过两种方式对类成员进行初始化,可以使用成员初始化列表(推荐),也可以使用使用赋值语句。

1)使用成员初始化列表

成员初始化列表更高效,初始化列表直接调用成员的构造函数初始化成员变量。如果使用赋值语句,成员变量会先默认初始化(调用默认构造函数),再被赋值,这可能导致两次构造,效率低。

#include <iostream>
#include <string>
using namespace std;

class MyClass {
    int x;
    std::string name;

public:
    // 构造函数:使用成员初始化列表
    MyClass(int a, std::string n) : x(a), name(n) {}

    // 添加成员访问函数
    void display() const {
        std::cout << "x: " << x << ", name: " << name << std::endl;
    }
};

int main() {
    // 创建对象,自动调用带成员初始化列表的构造函数
    MyClass obj(42, "Alice");

    // 调用成员函数输出内容
    obj.display();

    return 0;
}

2)使用赋值语句

#include <iostream>
#include <string>
using namespace std;

class MyClass {
    int x;
    std::string name;

public:
    // 构造函数,不使用成员初始化列表
    MyClass(int a, std::string n) {
        x = a;
        name = n;
    }

    // 成员函数,用于显示成员变量
    void display() const {
        std::cout << "x = " << x << ", name = " << name << std::endl;
    }
};

int main() {
    // 创建对象并传入参数
    MyClass obj(42, "Example");

    // 调用成员函数输出成员信息
    obj.display();

    return 0;
}

2、某些类型必须通过初始化列表初始化

const 成员变量,引用类型(T&),没有默认构造函数的成员对象等必须通过初始化列表初始化。

#include <iostream>
#include <string>
using namespace std;

class MyClass {
    const int id;   // 常量成员,必须在初始化列表中初始化
    int& ref;       // 引用成员,也必须在初始化列表中初始化

public:
    MyClass(int i, int& r) : id(i), ref(r) {}

    void display() const {
        std::cout << "id = " << id << ", ref = " << ref << std::endl;
    }

    void updateRef(int newVal) {
        ref = newVal; // 修改的是原始变量的值
    }
};

int main() {
    int value = 42;
    MyClass obj(1, value);

    obj.display();  // 输出: id = 1, ref = 42

    obj.updateRef(100);
    obj.display();  // 输出: id = 1, ref = 100

    std::cout << "Original value: " << value << std::endl;  // 输出: 100

    return 0;
}

3、可以避免默认构造的问题

对于没有默认构造函数的成员对象,使用赋值语句会导致编译错误,而初始化列表可以直接调用参数构造函数。

#include <iostream>
using namespace std;

class NoDefault {
public:
    NoDefault(int x) {
        std::cout << "NoDefault constructed with value: " << x << std::endl;
    }
};

class A {
    NoDefault nd;

public:
    A() : nd(10) {  // 使用成员初始化列表初始化 nd
        std::cout << "A constructed" << std::endl;
    }
};

int main() {
    A a;  // 创建 A 对象,将调用 NoDefault(10)
    return 0;
}

推荐文档