new建立乙個物件,是否需要加括號?

2021-06-18 15:16:23 字數 2445 閱讀 8582

**

問:假設有class test,那麼以下兩種寫法有何不同?

寫法1、test* test = new test;

寫法2、test* test = new test();

答:這需要很細緻的專研,因為兩種寫法的區別雖然細微,但會導致不同的執行結果。

test是否是pod型別,是否包含pod成員並且採用編譯器自動產生的預設建構函式,都會關係到new分配得到的記憶體是否初始化。

在c++98標準中,有兩種初始化,即zero initialization和default initialization。(概念、術語,不知道該怎麼翻譯,保留英文原文)

在c++03標準中,還新增了第三種,即value initialization。

以上三種initialization的區別,參見譯註第2條。

考慮這段**:

[cpp]view plain

copy

print?

struct

a ; 

// pod

struct

b ; 

// non-pod, compiler generated default ctor

struct

c ; ~c(); 

intm; }; 

// non-pod, default-initialising m

在c++98標準中,會是這樣:

new a   - m的值不確定

new a() - m的值為零

new b   - default construct (m沒有被初始化)

new b() - default construct (m沒有被初始化)

new c   - default construct (m初始化為零)

new c() - default construct (m初始化為零)

在c++03標準中,會是這樣:

new a   - m的值不確定

new a() - 進行value initialization,由於a是pod型別,所以實際上執行zero initialization,結果m初始化為零

new b   - 進行default initialization,m沒有被初始化

new b() - 進行value initialization,因為建構函式是編譯器自動產生(而不是使用者自己定義),所以會對所有成員執行zero initialization,結果m初始化為零

new c   - 進行default initialization,呼叫建構函式,m初始化為零

new c() - 進行value initialization,呼叫建構函式,m初始化為零

綜合起來看,有兩個需要注意的地方:

1、在兩種c++標準中,對於pod型別struct a來說,new a和new a()的結果會不同。寫了括號會把結構體的成員賦值為零,沒寫括號就不會。

2、對於new b(),在c++98標準和c++03標準的行為不一致。前者不會把成員變數初始化為零,而後者會。

這是c++的陰暗角落之一,不小心的話可能會讓你發瘋。用new建立物件時,有時需要加括號,有時基本不能加括號,有時不管加不加括號皆可。

譯註:1、經visual studio 2008試驗,int* p1 = new int; int* p2 = new int();,則*p1是乙個不確定的值,而*p2等於零。

2、什麼叫default initialization,什麼叫value initialization,什麼叫zero initialization,這裡還有一篇。大致翻譯如下:

zero initialization的定義:對於標量型別(scalar type),初始化為零;對於non-union的class(或者struct)型別,每個成員和每個基類都進行zero initialization(遞迴定義);對於陣列,每個成員都進行zero initialization(遞迴定義);對於union,第乙個成員被zero initialization;對於引用,不執行任何動作。

default initialization的定義:對於non-pod型別,呼叫預設建構函式(若預設建構函式不能訪問,則出錯);對於陣列,每個成員都進行default initialization(遞迴定義);其它情形,視作與zero initialization一致。

value initialization的定義:如果有使用者定義的建構函式,則呼叫預設建構函式(若預設建構函式不能訪問,則出錯);對於non-union的class(或者struct)型別,且沒有使用者定義的建構函式,每個成員和每個基類都進行value initialization;對於陣列,每個成員都進行value initialization;其它情形,視作與zero initialization一致。

3、翻譯有些許遺漏,只記錄了我覺得比較重要的內容。這裡翻譯的作用主要是:(1)備忘;(2)讓更多人知道;(3)讓我們讀得更快。但如果需要準確理解,還是建議讀一讀原文。

判斷乙個物件是否有new

c 語言中,物件沒有空和不空的概念,只有物件指標才有空和不空的概念 判斷物件指標是否為空只需要和null常量進行比較即可 如果相等,則為空,否則不為空 另外物件雖然沒有空和不空的概念,但是有有效和無效的概念 當物件的析構函式被呼叫之後,物件即成為乙個無效物件 一般可以用控制代碼法來判斷 當物件被構造...

判斷乙個物件是否為Buffer物件

1 問題背景 不同資料型別物件變數,如何判斷乙個物件是否為buffer物件 2 實現原始碼 you anikdjfijkfjkdsjfkdjfkdjfkdjfkdjfkd anikdjfijkfjkdsjfkdjfkdjfkdjfkdjfkd hai buffer 128 typeof you st...

判斷乙個物件是否為陣列

方法一 使用instanceof操作符。instanceof操作符用來判斷要檢測物件的原型鏈上是否存在某個建構函式的prototype屬性。var a var b console.log a instanceof object true console.log b instanceof object...