CPP的初始化方式

  • content {:toc}

1 C++ 11 之前的初始化方式

C++ 11 之前初始化的方式可以分为:直接初始化、拷贝初始化和大括号列表初始化

直接初始化

这个最好理解,直接用显式的构造调用初始化,基本数据类型同样适用

1
2
int j(0);
MyClass myclass(123); //Foo is a class

拷贝初始化

1
2
int i = 0;
MyClass myclass;  //Foo is a class

大括号列表初始化

这种列表初始化方式仅限于有限的几种类型:数组和 POD 类型(plain old data 类型,指的是这样一些数据类型:基本数据类型、指针、union、数组、构造函数是 trivial 的 struct 或者 class 等与 C 相兼容的数据类型,可以按照 C 的方式来处理(运算、拷贝等))

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 列表初始化 C11
vector<vector<int> > map = {     {1, 0}, {-1, 0}, {0, 1}, {0, -1} };

// 如果有些元素没有指定, 那么就会默认初始化
int arr[4] = { 1, 2, 3 };

// 默认值的初始化, 全部是 0
int a[26] ={};
int a[26]{};

struct A{
    int i;
    struct B{
        int j;
        int k;
    } b;
} a = { 1, { 2, 3 } };  //POD类型

C++ 11 提供了统一的列表初始化方式

以下内容来自chatgpt

C++列表初始化(List Initialization)是一种用于初始化对象、数组和容器的新语法。它在C++11标准中引入,并在后续的C++14、C++17和C++20中得到进一步扩展和改进。列表初始化通过使用花括号 {} 来简化初始化语法,同时提高代码的安全性和可读性。

列表初始化的类型

列表初始化主要有以下几种类型:

  1. 直接列表初始化:

    直接在对象创建时使用花括号进行初始化。

    1
    2
    
    int x{5}; // 直接列表初始化
    double y{3.14};
    
  2. 拷贝列表初始化: 使用等号和花括号进行初始化。

    1
    2
    
    int x = {5}; // 拷贝列表初始化
    double y = {3.14};
    
  3. 聚合初始化: 用于聚合类型(如结构体、数组等)的初始化。

    1
    2
    3
    4
    5
    6
    7
    
    struct Point {
        int x;
        int y;
    };
    
    Point p = {1, 2}; // 聚合初始化
    int arr[] = {1, 2, 3, 4}; // 数组的聚合初始化
    
  4. 范围for循环: 使用范围for循环遍历列表初始化的容器。

    1
    2
    3
    4
    
    std::vector<int> vec = {1, 2, 3, 4, 5};
    for (int n : vec) {
        std::cout << n << ' ';
    }
    
  5. 标准库容器的列表初始化: 初始化标准库容器,如 std::vectorstd::array 等。

    1
    2
    
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::array<int, 4> arr = {1, 2, 3, 4};
    

列表初始化的优势

  1. 避免窄化转换: 列表初始化不会允许从浮点到整数、较大范围整数到较小范围整数等潜在的危险转换。

    1
    
    int x{3.14}; // 错误,不能从double到int的窄化转换
    
  2. 统一的初始化语法: 提供了一种统一的对象初始化语法,提高了代码的一致性和可读性。

    1
    2
    3
    
    int x{5};
    double d{3.14};
    std::vector<int> vec{1, 2, 3, 4};
    
  3. 更简洁的代码: 列表初始化语法通常比传统的构造函数调用更简洁和直观。

    1
    
    std::vector<int> vec = {1, 2, 3, 4}; // 比 vec.push_back(1); vec.push_back(2); 等更简洁
    

列表初始化的示例代码

以下是一些具体的列表初始化示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
#include <array>

struct Point {
    int x;
    int y;
};

int main() {
    // 直接列表初始化
    int a{10};
    double b{3.14};
    
    // 拷贝列表初始化
    int c = {15};
    double d = {2.71};
    
    // 聚合初始化
    Point p = {1, 2};
    int arr[3] = {4, 5, 6};
    
    // 标准库容器的列表初始化
    std::vector<int> vec = {7, 8, 9, 10};
    std::array<int, 4> arr2 = {11, 12, 13, 14};
    
    // 输出测试
    std::cout << "a: " << a << ", b: " << b << '\n';
    std::cout << "c: " << c << ", d: " << d << '\n';
    std::cout << "Point p: (" << p.x << ", " << p.y << ")\n";
    
    std::cout << "arr: ";
    for (int i : arr) {
        std::cout << i << ' ';
    }
    std::cout << '\n';

    std::cout << "vec: ";
    for (int i : vec) {
        std::cout << i << ' ';
    }
    std::cout << '\n';

    std::cout << "arr2: ";
    for (int i : arr2) {
        std::cout << i << ' ';
    }
    std::cout << '\n';

    return 0;
}

以上代码展示了不同情况下的列表初始化使用方法及其输出结果。列表初始化不仅能使代码更清晰,还能防止许多潜在的错误,是C++11及以后标准推荐的初始化方式。

Licensed under CC BY-NC-SA 4.0
最后更新于 Oct 13, 2024 18:49 +0800
使用 Hugo 构建
主题 StackJimmy 设计