欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 《C++11》各种初始化方式的详细列举与对比

《C++11》各种初始化方式的详细列举与对比

2025/5/12 21:25:32 来源:https://blog.csdn.net/Z_oioihoii/article/details/144970023  浏览:    关键词:《C++11》各种初始化方式的详细列举与对比

生成特定比例卡通程序员图片.png

在 C++ 中,初始化对象的方式多种多样。随着 C++ 标准的演进,特别是 C++11 的引入,初始化方式得到了显著的扩展和改进。本文将详细列举 C++ 中的各种初始化方式,并对它们进行对比,帮助开发者更好地理解和应用这些特性。

1. C++98/C++03 的初始化方式

在 C++98 和 C++03 中,主要有以下几种初始化方式:

1.1 直接初始化(Direct Initialization)

使用构造函数直接初始化对象。

int a(5);                     // 直接初始化整数
std::vector<int> v(5, 1);    // 直接初始化 STL 容器,创建一个包含 5 个元素的 vector,每个元素为 1

1.2 复制初始化(Copy Initialization)

使用赋值操作符 = 进行初始化。

int b = 5;                    // 复制初始化整数
std::vector<int> w = std::vector<int>(5, 1); // 复制初始化 STL 容器

1.3 动态初始化(Dynamic Initialization)

使用 new 关键字动态分配内存并初始化对象。

int* p = new int(5);         // 动态初始化整数
std::vector<int>* vec = new std::vector<int>(5, 1); // 动态初始化 STL 容器

1.4 列表初始化(List Initialization)

在 C++98/C++03 中并不支持列表初始化,但可以使用初始化列表来初始化数组。

int arr[5] = {1, 2, 3, 4, 5}; // 初始化数组

2. C++11 及之后的初始化方式

C++11 引入了列表初始化,并对其他初始化方式进行了改进。以下是 C++11 及之后的初始化方式:

2.1 列表初始化(List Initialization)

使用大括号 {} 来初始化对象。

int a = {5};                    // 列表初始化整数
std::vector<int> v = {1, 2, 3}; // 列表初始化 STL 容器
2.1.1 命名列表初始化

可以为元组或结构体的成员命名(C++20 支持)。

struct Point {int x;int y;
};Point p = { .x = 1, .y = 2 }; // C++20 支持的命名初始化

2.2 直接初始化(Direct Initialization)

C++11 继续支持直接初始化。

int a(5);                     // 直接初始化整数
std::vector<int> v(5, 1);    // 直接初始化 STL 容器

2.3 复制初始化(Copy Initialization)

C++11 继续支持复制初始化。

int b = 5;                    // 复制初始化整数
std::vector<int> w = {1, 2, 3}; // 复制初始化 STL 容器

2.4 动态初始化(Dynamic Initialization)

C++11 继续支持动态初始化。

int* p = new int(5);         // 动态初始化整数
std::vector<int>* vec = new std::vector<int>{1, 2, 3}; // 动态初始化 STL 容器

2.5 统一初始化(Uniform Initialization)

C++11 引入的统一初始化方式,使用大括号 {},可以用于所有类型的对象。

int a{5};                     // 统一初始化整数
std::vector<int> v{1, 2, 3};  // 统一初始化 STL 容器

2.6 初始化类的非静态成员

在类定义中,可以直接使用列表初始化来初始化非静态成员。

struct Point {int x{0}; // 列表初始化int y{0};
};

2.7 结构体和类的初始化

C++11 允许使用列表初始化来初始化结构体和类。

struct Point {int x;int y;
};Point p{1, 2}; // 使用列表初始化结构体

3. 各种初始化方式的对比

初始化方式C++98/C++03C++11 及之后
直接初始化
复制初始化
动态初始化
列表初始化×
统一初始化×
防止窄化转换×√ (仅列表初始化)
初始化类的非静态成员×√ (仅列表初始化)
命名初始化×√ (C++20)

4. 深入理解 C++11 及以后的新特性

在 C++ 中,特别是 C++11 及以后的版本中,以下几个概念是非常重要的,它们帮助开发者编写更安全和更易于维护的代码。

4.1 防止窄化转换

定义

窄化转换(Narrowing Conversion)是指将一个较大范围的类型转换为一个较小范围的类型,这种转换可能会导致数据丢失。例如,将 double 转换为 int,或者将 long 转换为 short

示例
double d = 3.14;
int a = d; // 这是窄化转换,可能导致数据丢失

在 C++11 中,使用列表初始化(如 {})时,编译器会检查是否存在窄化转换。如果存在,编译器会报错,从而防止潜在的数据丢失。

int a = {3.14}; // 错误:窄化转换
优点
  • 安全性:防止了意外的数据丢失,增强了代码的安全性。
  • 可读性:通过编译器的错误提示,开发者可以更清晰地了解潜在的问题。

4.2 初始化类的非静态成员

定义

在 C++11 中,可以在类的定义中直接使用列表初始化来初始化非静态成员变量。这种方式使得类的构造更加简洁和直观。

示例
struct Point {int x{0}; // 列表初始化,x 默认初始化为 0int y{0}; // 列表初始化,y 默认初始化为 0
};Point p; // 创建 Point 对象,x 和 y 都会被初始化为 0
优点
  • 简洁性:在类定义中直接初始化成员变量,减少了构造函数的复杂性。
  • 可读性:使得类的默认状态更加明确,便于理解。

4.3 命名初始化

定义

命名初始化(Named Initialization)是指在初始化结构体或类时,可以为成员指定名称。这种特性在 C++20 中得到了正式支持,但在 C++11 中并没有直接的命名初始化语法。

示例(C++20)
struct Point {int x;int y;
};Point p{.x = 1, .y = 2}; // 使用命名初始化
优点
  • 可读性:通过为成员命名,代码的可读性大大提高,特别是在结构体或类有多个成员时。
  • 灵活性:可以在初始化时只指定部分成员,未指定的成员会使用默认值。

注意

在 C++11 中,虽然没有直接的命名初始化语法,但可以通过构造函数或其他方式实现类似的效果。

5. 总结

C++ 的初始化方式随着标准的演进而不断丰富,特别是 C++11 引入的列表初始化和统一初始化,使得代码更加简洁和安全。不同的初始化方式各有其适用场景,开发者可以根据具体需求选择合适的方式进行对象的初始化。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词