繁体   English   中英

这些初始化有什么区别?

[英]What is the difference between these initializations?

我以前知道未初始化的成员变量是用垃圾值初始化的。

但是,如果在 class 中存在未初始化的指针变量,则所有未初始化的成员变量都将初始化为零。

我认为指针变量只是指向堆 memory 中的一个实例。

为什么其他变量会改变?

我不知道这些初始化之间有什么区别。

下面是我一步一步尝试的代码。

#include <iostream>

using namespace std;

class Test {
private:
    int val1;
    int val2;

public:
    void PrintValue() {
        cout << "val1: " << val1 << endl;
        cout << "val2: " << val1 << endl;
    }
};

int main() {
    Test a;
    a.PrintValue();
}

那么,结果是

val1: -858993460
val2: -858993460

在这段代码中,我添加了'int* ptr = new int' ,如下所示。

#include <iostream>

using namespace std;

class Test {
private:
    int val1;
    int val2;
    int* ptr = new int;

public:
    void PrintValue() {
        cout << "val1: " << val1 << endl;
        cout << "val2: " << val1 << endl;
    }
};

int main() {
    Test a;
    a.PrintValue();
}

结果是这样的。

val1: 0
val2: 0

为什么会这样?

我正在使用 VS community 2019 并构建工具 v142。

没有改变。 由于默认初始化的影响,数据成员val1val2将被初始化为不确定值; 任何使用它们都会导致 UB,一切皆有可能。

否则,什么都不做:具有自动存储持续时间的对象(及其子对象)被初始化为不确定的值。

具有自动和动态存储持续时间的非类变量的默认初始化会产生具有不确定值的对象

这里的区别在于,添加int* ptr = new int会将您的 class 从POD (普通旧数据)class 更改non-POD class。
如果您尝试使用第一个示例

class Test {
public:
    int val1;
    int val2;

    void PrintValue() {
        cout << "val1: " << val1 << endl;
        cout << "val2: " << val1 << endl;
    }
};

int main() {

    Test t;
    cout << t.val1 << endl;
}

然后你会得到一个编译器错误,因为它知道你正在尝试访问未初始化的变量。

但是,当您添加更复杂的int* ptr = new int时,您的 class 将变为非 POD,因此编译器会为您创建一个默认构造函数,它将为您初始化变量。
所以

class Test {
public:
    int val1;
    int val2;
    int* ptr = new int;
    void PrintValue() {
        cout << "val1: " << val1 << endl;
        cout << "val2: " << val1 << endl;
    }
};

int main() {

    Test t;
    cout << t.val1 << endl;
}

这变得合法并且现在可以编译(尽管正如其他答案指出的那样,虽然 output 可能看起来更干净,并且不会抛出错误,访问这些默认的初始化变量可能仍然是 UB)

更多关于 POD 的信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM