如果我沒有定義自己的構造函數,Base *b = new Base;
與Base *b = new Base();
之間是否有區別?`Base * b = new Base;`vs`Base * b = new Base();`沒有定義我自己的構造函數
回答
初始化是一種遵循標準的PITA ...然而,兩個已經存在的答案在他們錯過的時候是不正確的,這使得他們肯定沒有區別。
在沒有用戶定義的構造函數的類中調用new T
和new T()
有很大區別。在第一種情況下,對象將是默認初始化,而在第二種情況下,它將被初始化*值。如果對象包含任何POD子對象,那麼第一個將離開POD子對象初始化,而第二個將各個子元件設置爲0。
struct test {
int x;
std::string s;
};
int main() {
std::auto_ptr<test> a(new test);
assert(a->s.empty()); // ok, s is string, has default constructor
// default constructor sets it to empty
// assert(a->x == 0); // this cannot be asserted, the value of a->x is
// undefined
std::auto_ptr<test> b(new test());
assert(b->s.empty()); // again, the string constructor sets to empty
assert(b->x == 0); // this is guaranteed by *value-initialization*
}
對於漫長的道路... 爲用戶默認初始化定義的類意味着調用默認的構造函數。在沒有用戶提供的默認構造函數的情況下,它將調用隱式定義的默認構造函數,它相當於一個具有空初始化列表和空主體的構造函數(test::test() {}
),這又會導致每個非空值的默認初始化 -POD子對象,並保留所有POD子對象未初始化。由於std::string
具有用戶(通過包括標準庫編寫器的用戶的某種定義)提供了構造函數,它將調用此構造函數,但它不會對x
成員執行任何實際初始化。
也就是說,對於一個類與用戶提供的默認構造函數,new T
和new T()
是相同的。對於沒有這樣的構造函數的類,它取決於類的內容。
for non native發言者(包括我):(1)http://en.wiktionary.org/wiki/PITA(2)http://stackoverflow.com/questions/146452/what-are-pod-types-in-c – 2010-09-13 08:38:14
謝謝對於鏈接@afriza。 – 2010-09-13 08:51:34
+1:現在指出我的迴應中的錯誤,並+1爲一個很好的答案,將它排隊以後!!做成我最喜歡的問題以及 – Chubsdad 2010-09-13 08:58:55
編輯:SEE @大衛的回答 - 這是錯誤的,但我不能刪除它,因爲它被接受
有在任何情況下沒有什麼區別 - 如果你把它定義不要緊,你的自己的構造函數與否。
唯一的區別是對於原始類型(即int
或float
),添加()
會將該值初始化爲零。 (Demonstration on Codepad)
參見本實施例中(輸出是上codepad)
#include <iostream>
struct ConstructorChecker
{
ConstructorChecker()
{
std::cout << "Hey look! A new constructor checker!" << std::endl;
}
};
struct BasicClass
{
};
int main()
{
//Note constructor called in both cases.
ConstructorChecker *one = new ConstructorChecker;
delete one;
ConstructorChecker *two = new ConstructorChecker();
delete two;
//Same deal -- just because the compiler provides the constructor doesn't mean
//it behaves any differently.
BasicClass *basic = new BasicClass;
delete basic;
BasicClass *basic2 = new BasicClass();
delete basic2;
return 0;
}
微妙而奇妙的差異。關於C++的那種讓你想知道的事情:_why_? – wilhelmtell 2010-09-13 03:52:43
我的錢與現有C++代碼的向後兼容性。 – 2010-09-13 03:57:06
@Mike:向後兼容性沒有任何意義,因爲'new'永遠是那樣的。我的猜測是,他們不希望用戶必須付費將內存初始化爲零,但他們希望提供'new'樣式的'calloc'替換(它要求將內存初始化爲零)。 '()'是一個合理的語法,因爲它看起來像你正在調用一個構造函數,它初始化任何其他類型的值。 – 2010-09-13 04:00:26
如比利提到的,兩者都是同一個。
這被稱爲'價值初始化語法'($ 8.5/7)。
一個對象,其初始化是 空的圓括號,即(), 應值初始化。
您引用了標準的正確部分,但您卻沒有注意到它的重要性...... – 2010-09-13 07:54:58
- 1. C#中的this()和base()構造函數
- 2. C#構造base關鍵字
- 3. 構造函數定義中的「:base」是什麼意思?
- 4. 在C#中將base-27(或base-X)轉換爲base-10?
- 5. 沒有函數的PL/SQL base轉換
- 6. Rails ActiveRecord :: Base定義了哈希構造函數?
- 7. PostgreSQL:有沒有函數可以將base-10 int轉換爲base-36字符串?
- 8. public class Extra <BASE> extends BASE
- 9. C++函數指針'base'
- 10. 運行時檢查一個實例(Base *)是否覆蓋父函數(Base :: f())
- 11. C++中的Abstract/Base結構?
- 12. CSS:background-images base
- 13. Go + Angular:loading base html
- 14. Base SDK Xcode 3.2.6
- 15. Java - Collection base
- 16. WPF Base Window
- 17. Base類4
- 18. Xcode中Base SDK的含義
- 19. '{「errors」:{「base」:[「Forbidden。Need user。」]}}'
- 20. convert inherited to generic base
- 21. 爲什麼新的Base()不能傳遞給<?擴展Base>?
- 22. java.lang.NoClassDefFoundError:com/google/common/base/Function
- 23. base mine他們的
- 24. 未定義的引用Base :: run();
- 25. 將Base 1數組更改爲Base 0 Array
- 26. 如何將base 2浮點數轉換爲base 10?
- 27. 爲什麼Base * pd = new Derived;產生一個錯誤?
- 28. 爲什麼base()構造函數不是必需的?
- 29. 默/ Base 64編碼
- 30. Flexslider Thumb Image Base 64
是第一個合法的C++代碼嗎? – 2010-09-13 03:55:34
@Rafe:是的,第一個是完全合法的。 (請參閱我的答案中的鍵盤鏈接) – 2010-09-13 03:58:34
接受的答案是**錯誤**。'new T'會*默認初始化*對象,而'new T()'會*初始化*它。 – 2010-09-13 08:28:44