名稱空間
變體
操作

零初始化

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

將物件的初始值設定為零。

目錄

[編輯] 語法

請注意,這並不是零初始化的語法,零初始化在語言中沒有專門的語法。這些是其他型別初始化的示例,它們可能會執行零初始化。

static T 物件 ; (1)
T () ;

T t = {} ;

T {} ; (C++11 起)

(2)
CharT 陣列 [ n ] = " 短序列 "; (3)

[編輯] 解釋

零初始化在以下情況下執行:

1) 對於每個具有靜態或執行緒區域性(C++11 起) 儲存期且不受常量初始化影響的具名變數,在任何其他初始化之前。
2) 作為非類型別和沒有建構函式的值初始化類型別的成員的值初始化序列的一部分,包括對於沒有提供初始化的聚合體元素的初始化。
3) 當任何字元型別的陣列用過短的字串字面量初始化時,陣列的其餘部分被零初始化。

零初始化的效果是:

  • 如果 T標量型別,則物件被初始化為透過將整數字面量0(零)顯式轉換T 所獲得的值。
  • 如果 T 是非聯合類型別
  • 所有填充位都被初始化為零位,
  • 每個非靜態資料成員都被零初始化,
  • 每個非虛基類子物件都被零初始化,並且
  • 如果物件不是基類子物件,則每個虛基類子物件都被零初始化。
  • 如果 T 是聯合型別
  • 所有填充位都被初始化為零位,並且
  • 物件的第一個非靜態具名資料成員被零初始化。
  • 如果 T 是陣列型別,則每個元素都被零初始化。
  • 如果 T 是引用型別,則不執行任何操作。

[編輯] 注意

非區域性初始化中所述,未進行常量初始化的靜態和執行緒區域性(C++11 起)變數在任何其他初始化發生之前都會被零初始化。如果非類非區域性變數的定義沒有初始化器,則預設初始化不執行任何操作,使先前零初始化的結果保持不變。

零初始化後的指標是其型別的空指標值,即使空指標的值不是整數零。

[編輯] 示例

#include <iostream>
#include <string>
 
struct A
{
    int a, b, c;
};
 
double f[3];   // zero-initialized to three 0.0's
 
int* p;        // zero-initialized to null pointer value
               // (even if the value is not integral 0)
 
std::string s; // zero-initialized to indeterminate value, then
               // default-initialized to "" by the std::string default constructor
 
int main(int argc, char*[])
{
    delete p; // safe to delete a null pointer
 
    static int n = argc; // zero-initialized to 0 then copy-initialized to argc
    std::cout << "n = " << n << '\n';
 
    A a = A(); // the effect is same as: A a{}; or A a = {};
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

可能的輸出

n = 1
a = {0 0 0}

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
CWG 277 C++98 指標可能用值為 0 的非常量表達式初始化,這並不是一個空指標常量
指標可能用值為 0 的非常量表達式初始化,這並不是一個空指標常量
必須用值為 0 的整數常量表達式初始化
必須用值為 0 的整數常量表達式初始化
CWG 694 C++98 類型別的零初始化忽略填充 填充被初始化為零位
CWG 903 C++98 標量型別的零初始化將初始值設定為從值為 0 的整數常量表達式轉換而來的值
標量型別的零初始化將初始值設定為從值為 0 的整數常量表達式轉換而來的值
物件被初始化為從整數字面量0轉換而來的值
物件被初始化為從整數字面量0轉換而來的值
CWG 2026 C++98 零初始化總是被指定為最先發生,甚至在常量初始化之前
零初始化總是被指定為最先發生,甚至在常量初始化之前
如果適用常量初始化,則不進行零初始化
如果適用常量初始化,則不進行零初始化
CWG 2196 C++98 類型別的零初始化忽略基類子物件 它們也零初始化
CWG 2253 C++98 不清楚零初始化是否適用於未命名的位域
不清楚零初始化是否適用於未命名的位域
它適用(所有填充位都被初始化為零位)
它適用(所有填充位都被初始化為零位)

[編輯] 另請參閱