2009-07-17 139 views
8

代碼示例應該解釋的事情:C++:成員指針初始化?

class A 
{ 
    B* pB; 
    C* pC; 
    D d; 

    public : 
    A(int i, int j) : d(j) 
    { 
     pC = new C(i, "abc"); 
    } // note pB is not initialised, e.g. pB(NULL) 

    ... 
}; 

顯然的pB應當被初始化爲NULL,明確地是安全的(和明確的),但是,因爲它的立場,什麼是PB的建設後的價值?它是否默認初始化(它是零?)還是不存在(即不確定和內存中的任何內容)。我意識到在C++中初始化有一些公平的規則。

我認爲這不是默認初始化;在Visual Studio中以調試模式運行時,它將pB指向0xcdcdcdcd--這意味着內存已經被新建(在堆上),但未初始化。但是在釋放模式下,pB總是指向NULL。這是偶然的,因此不能被依賴;還是這些編譯器爲我初始化它(即使它不在標準中)?在Sun的Solaris編譯器上進行編譯時,它似乎也是NULL。

我真的很想找一個具體的標準來說一種或另一種說法。

謝謝。

+4

不確定(和一些編譯器會警告),但我沒有C++標準方便... – ephemient 2009-07-17 16:21:11

+4

B是一個隨機指向野外的指針。注意。在調試模式下,大多數編譯器會將其初始化爲NULL(據說有助於調試)。但在發佈模式下,它將具有先前在內存中的值。 – 2009-07-17 16:25:32

回答

11

下面是相關通道fromt他標準:

12.6.2初始化鹼和成員[class.base.init]

4如果一個給定的非靜態數據成員或 基類不是通過在 MEM-初始化-list中的MEM-
初始化-ID命名,然後

- - 如果該實體是 構件(可能CV修飾)0123非靜態數據類類型(或其數組)或基類,實體類 是非POD類,實體是默認初始化的(dcl.init)。 如果實體是一個const限定類型的非靜態數據成員,實體類應該有一個用戶聲明的默認構造函數。

- 否則,該實體不是 初始化。如果該實體是const限定類型或引用類型的實體,或者包含(直接或間接地)包含const限定類型成員的(可能是cv-quali- )POD類類型(或其數組)程序是 ill- 組成。

調用的 X類構造函數後已經完成,如果成員

X的

既不在 構造的MEM-初始化規定,也不
默認初始化,也不執行期間初始化
的構造函數體,成員有 不確定值。

+2

所以它是未初始化的,並且可以指向任何東西。內容可以通過實現來填充,即debugheap庫的fdfdfdfd。 – xtofl 2009-07-17 17:24:10

1

我相信這是一個很好的舊C時代的工件,當你無法預期alloc'd內存包含什麼時。隨着標準發展到C++,這個「約定」得以保留。隨着C++編譯器的開發,各位作者自行解決這個問題。因此,您的里程可能會因您選擇的編譯器而異。

「0xcdcdcdcd」看起來是一個容易識別的模式,可以幫助您調試代碼。這就是它在發佈模式下不顯示的原因。

我希望這有助於一點點和祝你好運。

0

未初始化的指針可指向任何內容。一些編譯器廠商會幫助你,並使它們指向0或0xcdcdcdcd或其他。

爲了確保您的代碼安全可靠,您應始終初始化您的指針。無論是0還是有效值。

例如

C* pc = 0; 

C* pc = new C(...); 

如果你總是初始化指針爲0,那麼這是安全的:

if (!pc) 
    pc = new C(...); 

如果你不初始化,然後你有沒有講些初始化方式和未初始化的指針分開。

另一方面,C++中沒有這樣的關鍵字爲NULL。大多數編譯器將NULL定義爲0,但它不被認爲是可移植的。新的C++ 0x標準將引入一個新的關鍵字nullptr,所以當它出現時,我們終於有一個可移植的空指針常量。

0

pB的值是未定義的。它可能會也可能不是一致的價值 - 通常取決於之前分配特定A實例之前在內存中的相同位置。

0

未初始化的指針允許基本上包含一個隨機值,儘管一些編譯器傾向於用0或其他可識別的值填充它們,尤其是在調試模式下。恕我直言,這是由於C++的「不支付你不使用的」設計。如果你認爲它不重要,編譯器不需要花費爲你初始化變量。當然,一旦你追逐了一個隨機指針,你可能會發現下一次初始化它是審慎的...

4

根據C++0x standard第12.6.2.4節,如果你的指針變量,如果你不喜歡將其包含在初始化程序列表中,並且不將其設置在構造函數的主體中,則它具有不確定的值。 0xCDCDCDCD和0是兩個可能的值,就像其他的一樣。 :-)

0

我很少會建議您不要學習您正在使用的語言,但在這種情況下,是否初始化pB並不是有用的信息。只需初始化它。如果它自動初始化,編譯器會優化額外的初始化。如果不是,那麼您已經添加了一條額外的處理器指令,並防止了大量潛在的錯誤。