C++中的初始化列表是一种方便且强大的工具,用于在创建对象时初始化成员变量。初始化列表在C++中广泛应用于各种类型的对象,包括数据成员、静态成员、常量成员等。初始化列表的主要优势在于,它允许程序员在对象创建时指定初始值,而不是在构造函数中。这可以提高效率,并减少因多次构造而产生的开销。
以下是一些常见的初始化方式:
直接赋值
这是最简单的初始化方式,直接在类定义中为成员变量赋值。例如:
class MyClass {
int a = 10; // 直接赋值初始化
};
构造函数初始化列表
这是使用构造函数初始化列表来初始化成员变量。这种方式可以保证成员变量在构造函数体执行之前被正确初始化。例如:
class MyClass {
int a;
public:
MyClass(int b) : a(b) {} // 使用构造函数初始化列表初始化a
};
委托构造函数初始化列表
这是一种更高级的初始化方式,使用委托构造函数来初始化成员变量。例如:
class MyClass {
int a;
public:
MyClass(int b) : MyClass(b) {} // 委托构造函数初始化列表初始化a
MyClass(int b) : a(b) {} // 在委托构造函数中初始化a
};
默认构造函数初始化列表
这是使用默认构造函数初始化列表来初始化成员变量。这种方式适用于没有显式定义构造函数的情况。例如:
class MyClass {
int a;
public:
MyClass() : a(0) {} // 使用默认构造函数初始化列表初始化a
};
命名初始化列表
这是使用命名初始化列表来初始化成员变量。这种方式可以提高代码可读性。例如:
class MyClass {
int a;
public:
MyClass : a(10) {} // 使用命名初始化列表初始化a
};
初始化列表的顺序和作用域
在C++中,初始化列表的顺序并不影响执行顺序,而是按照代码中声明的顺序执行。同时,每个类型只会被初始化为一次,即使它在多个初始化列表中出现。例如:
class MyClass {
int a;
int b;
public:
MyClass() : a(1), b(2), a(3) {} // a会被初始化为3,b会被初始化为2,但a不会被初始化为1,因为每个类型只会被初始化为一次。
};
初始化常量成员
在C++中,常量成员一旦被初始化就不能更改。这通常在类定义中完成。例如:
class MyClass {
const int a = 10; // 初始化常量成员a
};
使用列表初始化
列表初始化是一种更为直观且类型安全的初始化方式,它允许我们明确指定每个成员的初始值。例如:
class MyClass {
int a;
public:
MyClass(int b) : a{b} {} // 使用列表初始化初始化a
};
初始化引用成员
引用成员一旦被初始化就不能更改,这通常在类定义中完成。例如:
class MyClass {
int& a = *new int(10); // 初始化引用成员a
};
默认的构造函数和析构函数
当我们在类中没有定义构造函数和析构函数时,编译器会自动为我们生成默认的构造函数和析构函数。例如:
class MyClass {
int a;
public:
MyClass() = default; // 定义默认构造函数
~MyClass() = default; // 定义默认析构函数
};
需要注意的是,默认构造函数和析构函数不是我们可以在类定义中指定的唯一类型的构造函数和析构函数。我们还可以显式地定义其他类型的构造函数和析构函数,包括拷贝构造函数、移动构造函数、拷贝析构函数、移动析构函数等。