變量的默認初始化和值初始化


值初始化和默認初始化的適用場景:

值初始化:

(1)在數組初始化的過程中,如果提供的初始值數量少於數組的大小,剩下的元素會進行值初始化;

(2)靜態static變量定義在塊作用域外的全局變量如果沒有顯式的初始值,將執行值初始化;

(3)當我們通過書寫形如T()的表達式(例如 int())顯式地請求值初始化時;

 

默認初始化:

(1)當我們在塊作用域內類內也屬於塊作用域內)不使用任何初始值定義一個非靜態變量時;

(2)當一個類本身含有類類型成員且使用合成的默認構造函數時;

(3)當類類型的成員沒有在構造函數初始值列表中顯式地初始化時;

 

一、相關概念:

聲明:在環境/上下文中指定一個變量的名字。也就是說,聲明僅僅是讓編譯器知道,而沒有實際分配空間

初始化:給一個聲明后尚未初始化的變量一個有意義的初始值。

賦值 : 銷毀一個變量原來的值,並賦予一個新值。相當於改變了一個變量的狀態

 

二、初始化是在聲明一個變量的同時賦予它一個值,而賦值是已經聲明過了變量,后續再對它進行賦值操作。對於內置類型:

//在一個塊作用域內
{ 
    int i;    //默認初始化,其值未定義
    int j=0;  //值初始化
    j=1;      //賦值
}

 

 三、對於定義了自己的構造函數的類類型(例如string)來說,不管采用默認初始化還是值初始化,對象都會通過默認構造函數來初始化。

        但對於內置類型,值初始化的內置類型對象有着良好定義的值,而默認初始化的對象的值則是未定義的。

        對於類中那些依賴於編譯器合成的默認構造函數的內置類型成員,如果他們未在類內被初始化,那么它們的值也是未定義的。

 1     string *ps1 = new string;     //默認初始化為空string
 2     string *ps2 = new string();   //值初始化為空string
 3     int *pi1 = new int;           //默認初始化;*pi1的值未定義
 4     int *pi2 = new int();         //值初始化為0;*pi2為0
 5 
 6 
 7     class X
 8     {
 9         int a;
10     public:
11         void ShowX()
12         {
13             cout << a ;
14         }
15         X() = default;
16     };
17     int main()
18     {
19         X xx;
20         xx.ShowX();    //對象xx中的a成員的值被默認初始化,由於a是在塊作用域內定義的,所以此處輸出的值未定義
21 
22         return 0;
23     }

 

 

 

四、定義於塊作用域內(類內也屬於塊作用域內)的內置類型變量將不被初始化,其值未定義;定義於塊作用域外的全局變量被值初始化為0。

靜態static變量如果沒有顯式的初始值,它將執行值初始化。

 

 1 class X
 2 {
 3     int a;           
 4 public:
 5     void ShowX(){cout << a ;}
 6     X() = default;
 7 };
 8 int main()
 9 {
10    X xx;
11    xx.ShowX();    //對象xx中的a成員的值被默認初始化,由於a是在塊作用域內定義的,所以此處輸出的值未定義
12 
13    return 0;
14 }

 

五、對於自定義類型和STL中的容器,

class A;
A a=A();//值初始化
std::vector<int> vec1;//默認初始化,調用默認構造函數

一個類對象進行默認初始化和值初始化,必須要有相應的默認構造函數。否則將會報錯,因為無法構造這個類。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM