簡體   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