列表初始化(List Initialization)是C++11引入的一种初始化语法,使用花括号 {} 来进行对象的初始化。它提供了一种统一的方式来初始化各种类型的对象,包括基本数据类型、数组、结构体、类等。列表初始化有以下几种形式:
直接列表初始化:使用 {} 直接初始化对象。
拷贝列表初始化:使用 ={} 进行初始化。
直接列表初始化
直接列表初始化使用 {} 直接在变量声明时进行初始化。例如:
int a{5}; // 直接列表初始化一个整数
std::vector<int> vec{1, 2, 3}; // 直接列表初始化一个 vector
拷贝列表初始化
拷贝列表初始化使用 ={} 进行初始化。例如:
int a = {5}; // 拷贝列表初始化一个整数
std::vector<int> vec = {1, 2, 3}; // 拷贝列表初始化一个 vector
示例
以下是一些使用列表初始化的示例:
// 基本数据类型
int x{10};
double y{3.14};
// 数组
int arr[3]{1, 2, 3};
// 结构体
struct Point {
int x;
int y;
};
Point p{1, 2};
// 类
class MyClass {
public:
MyClass(int a, int b) : a_(a), b_(b) {}
private:
int a_;
int b_;
};
MyClass obj{1, 2};
// 智能指针
std::shared_ptr<int> ptr{new int(10)};
优点
统一初始化语法:列表初始化提供了一种统一的初始化方式,减少了不同初始化语法的混淆。
防止窄化转换:列表初始化不允许隐式的窄化转换,这有助于避免一些潜在的错误。
初始化列表构造函数:对于支持初始化列表的类(如 std::vector、std::map 等),列表初始化可以方便地进行初始化。
注意事项
窄化转换:列表初始化不允许隐式的窄化转换,例如将 double 转换为 int 会导致编译错误。
构造函数选择:在使用列表初始化时,编译器会优先选择使用初始化列表构造函数(如果存在),而不是其他构造函数。
总之,列表初始化是一种强大且灵活的初始化方式,广泛应用于现代C++编程中。
例子:
std::shared_ptr<UpdateEngine> update_engine_server{std::shared_ptr<UpdateEngine>(new UpdateEngineService())};
// 创建一个指向 UpdateEngine 类型的 shared_ptr,并将其初始化为指向新创建的 UpdateEngineService 实例。
// 这意味着 update_engine_server 将管理 UpdateEngineService 对象的生命周期,并在不再需要时自动释放其内存。
std::shared_ptr update_engine_server{std::shared_ptr(new UpdateEngineService())};
这里的 {} 是用于直接列表初始化 update_engine_server 对象。具体来说,它创建了一个 std::shared_ptr 对象,并将其初始化为指向新创建的 UpdateEngineService 实例。
所以,{} 在这里确实是赋值的意思,但它是一种特殊的初始化方式,称为列表初始化。这种方式在C++11及以后的版本中被广泛使用,因为它提供了更一致和安全的初始化语法。