2012-01-08 268 views
6

我正在學習ctors並且有幾個問題。在這些行:C++對象創建和構造函數

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

第一部分:只有1稱爲構造(美孚)和obj被初始化。所以,1個對象的創建。

第二部分:創建臨時對象obj2,爲其調用默認ctor。接下來我們創建Foo的另一個副本,並將其副本傳遞到operator=()。是對的嗎?所以,3個本地臨時對象,2個構造函數調用。

第三部分:創建1個對象Foo並將其副本傳遞到operator=()。所以,2個臨時對象和1個Ctor調用。

我理解這個權利嗎?如果這是真的,編譯器(例如最後的gcc)在常見情況下優化這些嗎?

+0

'operator =()'通常通過引用接收它的參數,所以在調用它時沒有副本。 – rodrigo 2012-01-08 11:59:53

+0

obj3實際上是使用複製構造函數而不是指定操作符創建的。 – 2012-01-08 11:59:56

回答

6

我將在第三個華富首評:

Foo obj3=Foo(args); 

它不使用operator=被稱爲拷貝賦值。相反,它調用複製構造函數(理論上)。這裏沒有任務。所以從理論上講,有兩個對象創建,一個是臨時的,另一個是obj3。編譯器可以優化代碼,完全消除臨時對象的創建。

現在,第二個:

Foo obj2;   //one object creation 
obj = Foo(args); //a temporary object creation on the RHS 

這裏的第一行創建一個對象,調用默認的構造函數。然後它調用operator=傳遞由表達式Foo(args)創建的臨時對象。所以有兩個對象只有operator=參考const參考(這是它應該做的)。

而對於第一個,你是對的。

+0

好的,謝謝。但無論如何,在第一種情況下,只有1個'Foo'類型的對象被創建,第三個:2個對象? – Ockonal 2012-01-08 12:01:27

+0

不,根據規格,第1部分和第3部分是指定相同事物的兩種方式。實施沒有區別。 – 2012-01-08 12:11:42

+2

@MrLister:不。「1」和「3」之間有細微的差別。只需編寫一個測試代碼,並使複製構造函數爲private。第一個會編譯,第三個不會! – Nawaz 2012-01-08 12:21:45

3
  1. 是的,Foo obj(args)創建一個Foo對象並調用一次ctor。

  2. obj2不被視爲臨時對象。但就像1 Foo obj2創建一個對象並調用Foo ctor。假設您的下一行代表obj2 = Foo(args),則此行創建一個臨時Foo對象,然後調用obj2.operator=()。因此,對於第二個示例,只有一個臨時對象,一個非臨時的,Foo ctors被調用兩次(一次是非臨時的,一次是臨時的),並調用operator =()一次。

  3. 不,這條線不叫operator=()。當使用=語法初始化obj3時,它幾乎和使用括號代替一樣:Foo obj3(Foo(args));因此,此行創建一個臨時對象,然後調用Foo copy ctor以使用該臨時對象初始化obj3。

1

您的術語有點混淆。

對象obj,obj2obj3不稱爲「臨時對象」。只有在分配給obj之前在第3行中創建的實例纔是臨時對象。此外,您不創建「Foo副本」,您可以創建「Foo實例」或「Foo類型對象」。