2016-12-29 105 views
3

我有一個基本的C++問題,我真的應該知道答案。在C++中創建類對象

假設我們有一些類A與構造函數A(int a)。是什麼區別:

A test_obj(4); 

A test_obj = A(4); 

我通常使用後一種語法,但在查找一些與我的可信C++入門無關的東西后,我意識到它們通常使用前者。這兩者之間的差異通常在內置類型的背景下討論(例如int a(6) vs int a = 6),我的理解是在這種情況下它們是等價的。

但是,在用戶定義類的情況下,是兩種定義對象等價的方法嗎?或者後者選項首先默認構造test_obj,然後使用A的複製構造函數將返回值A(4)指定爲test_obj?如果這是第二種可能性,我想這兩種方法在大型課堂上可能會有一些性能差異。

我確定這個問題是在互聯網上的某個地方回答的,即使在這裏,但我不能有效地搜索它,而沒有發現問題,詢問第一個選項和使用new之間的差異,這是不相關的。

+2

*我通常使用後一種語法* - 爲什麼?您將很難找到有經驗的C++程序員有意使用該語法。 – PaulMcKenzie

+0

@PaulMcKenzie沒有特別好的理由,我只是做。我願意改變。我從來沒有真正想過。 –

+0

@PaulMcKenzie回到原來的問題,有什麼區別? – jacknad

回答

4

A test_obj = A(4);概念確實構建一個臨時的A對象,然後從臨時複製/移動構造test_obj,然後破壞臨時。

然而,這個過程是copy elision的候選人,這意味着在驗證複製/移動構造函數存在並且可訪問之後,允許編譯器將其視爲A test_obj(4);

從C++ 17開始,編譯器必須執行此操作;在此之前它是可選的,但通常編譯器確實這樣做了。

+1

如果'A test_obj = A(4);'與'A test_obj = 4;'相同,那麼這是否意味着使用['explicit'說明符](http://en.cppreference.com/w/cpp/語言/顯式)會導致它拋出編譯時錯誤? – UnholySheep

+0

@UnholySheep好點。從我的答案中刪除了這一點,因爲它與OP的問題並不真正相關。 –

+0

顯式拷貝構造函數確實爲我打破了這一點。 –

3

性能方面,即使您有一個非標準的複製構造函數,它們也是等效的,正如copy elision所要求的那樣。這是自C++ 17以來保證的,但即使在符合早期標準的編譯器中也是如此。

自己嘗試,所有的優化關閉,被迫進入C++ 11的標準(或C++ 03,改變右上角的命令行): https://godbolt.org/g/GAq7fi