2014-04-15 73 views
1

見下面我的代碼:C++編譯器何時默認初始化指針?

class A 
{ 
public: 

    A() 
    { 
    i = 0; 

    if(pt != NULL) 
    { 
     std::cout << "why" << std::endl; 
    } 
    } 

    A(bool flag) 
    { 
    i = 0; 
    pt = new B(3.14); 
    } 

private: 

    class B 
    { 

    public: 
    B(double in) : j(in) {} 

    private: 
    double j; 
    }; 

private: 

    int i; 
    B *pt; 
}; 

int main(int argc, char *argv[]) 
{ 
    A obj; // place1 

    int *p; 

    if(p != NULL) 
    { 
    std::cout << "test2" << std::endl; 
    } 

    return 0; 
} 

在這一段代碼,我想知道,如果pt將被初始化@place1

另一個問題是,如果我刪除obj的定義,將會打印test2,如果不是,那麼爲什麼?

+1

正如所討論的[這裏] [1],指針在聲明時未被初始化。 [1]:http://stackoverflow.com/questions/1910832/why-arent-pointers-initialized-with-null-by-default – Codor

+0

靜態和全局變量初始化爲0。自動變量包含垃圾,並可能包含任何東西。 –

+0

[C中聲明的未初始化變量會發生什麼?它是否有價值?](http://stackoverflow.com/questions/1597405/what-happens-to-a-declared-uninitialized-variable-in-c-does-it-have-a-value) –

回答

1

p的值是未定義的。它可能是0或1或2或...... 因此,如果這是你的幸運日,你可能會得到一個否則不打印。

道德:不要依賴你得到的東西,自己初始化變量。

0

默認情況下,指針未初始化。你需要在你的構造函數(對於成員)或聲明的地方初始化它(對於局部變量)

+1

已與「指針」無關,與存儲類別無關。 –

0

C++不會爲你初始化你的實例變量。只要你不設置它們的值,它們就會有一個隨機值(或者看起來像隨機垃圾的值)。

+0

不完全正確。如果變量具有靜態存儲持續時間會發生什麼? –

+0

@EdS。相同(假設內置或POD)。或者你的意思是「靜態」? – juanchopanza

+0

...是的,我的意思是靜態的,謝謝。多任務失敗。 –

1

在這段代碼中,我想知道pt是否會被初始化@ place1。

它沒有被初始化爲任何東西。從技術上講,它是默認初始化,對於指針來說意味着不執行初始化。這意味着它可以保存任何值,並且它是未定義的行爲。

在C++ 11,如果你甲肝值初始化 OBJ,然後pt將是零初始化:

A obj{}; // obj.pt is nullptr 

另一個問題是,如果我刪除的定義obj,test2會打印,否則不會,爲什麼?

p也有一個未確定的值。它可以是NULL,但它可能不是。從中讀取的是未定義的行爲。因此,它有時可能會取值爲NULL,有時候不會,並且不能依賴可預測的行爲。

+0

爲什麼編譯器在默認情況下不會將指針初始化爲NULL? – xunzhang

+0

@xunzhang這是「你得到你所付出的」東西之一。 C++遵循C語言,允許您決定什麼時候內置類型(在某些情況下)是零初始化的,因爲您並不總是要對它們進行零初始化,而且這樣做並不是免費的。 – juanchopanza

+0

我不明白你的意思。編譯器將每個指針初始化爲NULL,如果要使用它,請自己初始化指針。這個問題有什麼問題? – xunzhang

-1
if(pt != NULL) 

可能是真的,因爲pt未在代碼中初始化爲NULL,它可以是任何值。指針應該由程序員在代碼中初始化爲NULL。
你可以閱讀this相關問題。瞭解它。

+1

'pt'也可以是'NULL'。 – juanchopanza

+0

@juanchopanza ya。它也可以是0,所以它也可以是NULL。好,謝謝 – LearningC

1

根據C++標準局部變量不是隱含地啓動的。所以在這個代碼片段中

int main(int argc, char *argv[]) 
{ 
    // ... 
    int *p; 
    // ... 

p沒有被編譯器隱式地初始化,因爲p是一個局部變量。如果p具有靜態存儲持續時間,則可以將其初始化爲零。例如

int *p; 

int main(int argc, char *argv[]) 
{ 
    // ... 

在這段代碼中,片段變量p將被初始化爲零。

對於類A,則在該代碼段

int main(int argc, char *argv[]) 
{ 
    A obj; // place1 

obj對象將是缺省初始化的是類的默認的構造將被調用。由於您不在構造函數中初始化數據成員pt,因此其值將不確定。

同樣,如果對象具有靜態存儲持續時間,那麼在調用默認構造函數之前,對象佔用的內存首先將被初始化。在這種情況下,pt將被初始化爲零初始化

A obj; 

int main(int argc, char *argv[]) 
{