介绍下 c++ 的初始化

一. 自动初始化为 0 的情况

在 C++中,初始化为 0 的情况取决于变量的类型、存储位置和初始化方式。以下是 C++中会自动初始化为 0 的几种情况:

1. 全局变量和静态变量

  • 全局变量(包括命名空间作用域的变量)和静态变量static)在定义时会被自动初始化为 0。

  • 这种自动初始化包括整型初始化为 0,浮点型初始化为 0.0,指针初始化为nullptr,类对象会调用默认构造函数。

    示例

    1
    2
    3
    4
    5
    6
    7
    int globalVar;          // 自动初始化为0
    static int staticVar; // 静态变量自动初始化为0

    int main() {
    static int funcStaticVar; // 函数内部的静态变量自动初始化为0
    return 0;
    }

2. 类中的非静态成员变量(使用值初始化)

  • 如果对象的非静态成员变量没有显式初始化,在值初始化时这些成员变量会被自动初始化为 0。

  • 值初始化通常发生在使用花括号初始化或默认初始化的情况下。

    示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct MyClass {
    int a;
    double b;
    };

    int main() {
    MyClass obj{}; // obj.a 和 obj.b 都会被初始化为0
    return 0;
    }

3. 数组的值初始化

  • 如果数组通过值初始化进行初始化,数组中的元素会被初始化为 0。

  • 通常使用花括号初始化或空花括号初始化的方式触发此行为。

    示例

    1
    2
    int arr1[5] = {};   // 所有元素初始化为0
    int arr2[5] = {0}; // 所有元素初始化为0

4. 动态分配的内存初始化

  • 使用new时,如果使用了带括号的方式,会将分配的内存初始化为 0。

  • 不加括号的new不会自动初始化(需要手动赋值)。

    示例

    1
    2
    3
    4
    int* p1 = new int();       // *p1 被初始化为0
    int* arr = new int[5](); // arr数组的每个元素都初始化为0
    delete p1;
    delete[] arr;

5. 内置类型的局部变量不会自动初始化

  • 如果是局部变量且不属于静态存储期的内置类型变量(如局部整型、浮点型或指针),则它们不会自动初始化为 0,值是未定义的,需手动初始化。

    示例

    1
    2
    3
    void func() {
    int localVar; // 未初始化,值未定义
    }

总结

C++中会自动初始化为 0 的主要情形包括全局/静态变量、类中的非静态成员变量(在值初始化时)、使用值初始化的数组和使用括号初始化的动态内存。

1. vector 初始化

1
std::vector<int> vec(5);

是的,使用这种方式定义 vector 时,编译器会自动将所有元素初始化为 0。

具体来说:

  1. 对于内置类型(如 int, double 等),会被初始化为 0
  2. 对于类类型,会调用默认构造函数

举例说明:

1
2
3
4
5
6
7
// 以下定义方式都会将元素初始化为0
std::vector<int> v1(5); // {0,0,0,0,0}
std::vector<double> v2(3); // {0.0,0.0,0.0}
std::vector<bool> v3(2); // {false,false}

// 类类型会调用默认构造函数
std::vector<std::string> v4(2); // {"",""}

所以 vector 中的所有 int 元素已经被初始化为 0 了。

二. 存放内置类型的容器初始化

在 C++中,存放内置类型的容器(如std::vector<int>)中的值是否会被初始化,取决于容器的构造和初始化方式。默认情况下,内置类型的元素不会自动初始化为 0,需要显式设置或采用某些特定的构造方式。以下是不同情况下的初始化行为:

1. 默认构造的容器

  • 如果使用默认构造的容器(即没有指定大小或初始值),则容器的内容为空。

  • 例如,std::vector<int> v;会创建一个空的vector,没有任何元素,因此不存在初始化的问题。

    示例

    1
    std::vector<int> v;  // 空容器,没有元素,因此没有初始化

2. 指定大小的构造方式

  • 如果通过指定大小来构造容器,例如std::vector<int> v(5);,容器会分配出对应数量的元素。

  • 对于内置类型的元素,使用此方式初始化时,值是未定义的,不会自动初始化为 0。

    示例

    1
    std::vector<int> v(5);  // 分配5个int元素,值未定义

3. 指定大小和初始值的构造方式

  • 使用std::vector<int> v(5, 0);指定大小并提供初始值时,所有元素都会被初始化为指定的值(此处为 0)。

  • 这种方式适用于确保容器中所有元素的初始值。

    示例

    1
    std::vector<int> v(5, 0);  // 分配5个元素,全部初始化为0

4. 使用std::array

  • std::array的大小是固定的,初始化时如果没有提供所有元素的初始值,未指定的元素会被自动初始化为 0。

  • 例如,std::array<int, 5> arr = {1};会将第一个元素初始化为 1,其他元素初始化为 0。

    示例

    1
    std::array<int, 5> arr = {1};  // arr = {1, 0, 0, 0, 0}

5. 使用std::vectorresize方法

  • 使用resize调整大小时,如果提供初始值参数(如v.resize(5, 0);),所有新元素会被初始化为指定值(这里是 0)。

  • 如果不提供初始值,则新元素的值未定义。

    示例

    1
    2
    std::vector<int> v;
    v.resize(5, 0); // 将容器扩展为5个元素,全部初始化为0

总结

  • **默认构造或仅指定大小的vector**:元素不会被初始化,值未定义。
  • **指定大小和初始值的vector**:元素会被初始化为指定值。
  • std::array初始化不完全填充:剩余元素会被初始化为 0。
  • resize时提供初始值:新元素会被初始化为该值。