2008-09-18 72 views
7

假設我有以下代碼:返回默認構造值有什麼問題嗎?

class some_class{}; 

some_class some_function() 
{ 
    return some_class(); 
} 

這似乎是工作得很好,節省了我要聲明一個變量只是做一回值的麻煩。但我認爲我從來沒有在任何教程或參考資料中看到過這一點。這是一個特定於編譯器的東西(Visual C++)嗎?或者這是否做錯了什麼?

回答

16

不,這是完全有效的。這也會更有效,因爲編譯器實際上能夠優化臨時性。

+0

實際上,現代編譯器通常能夠優化掉一個返回的命名變量 – 2008-09-18 20:32:13

1

這是完全合法的C++,任何編譯器都應該接受它。是什麼讓你覺得這可能是做錯了什麼?

+0

這只是我從來沒有真正看到它在我有限的C++經驗中的任何地方使用。 – 2008-09-18 20:28:49

+0

夠公平的。絕對使用它,如果沒有理由使用臨時變量,那麼你不必! – 2008-09-18 20:29:38

5

從函數調用返回對象是「工廠」設計模式,並廣泛使用。

但是,無論您是返回對象還是指向對象的指針,都需要小心。前者會向您介紹複製構造函數/賦值操作符,這可能會很痛苦。

2

它是有效的,但性能可能不理想,具體取決於它如何調用。

例如:

A a; 
a = fn(); 

A a = fn(); 

是不一樣的。

在第一種情況下,調用默認的構造函數,然後調用賦值運算符,該運算符需要構造一個臨時變量。

在第二種情況下使用複製構造函數。

一個足夠智能的編譯器將計算出可能的優化。但是,如果複製構造函數是用戶提供的,那麼我不會看到編譯器如何優化臨時變量。它必須調用複製構造函數,並且必須有另一個實例。

+1

該標準明確允許編譯器刪除拷貝構造函數。 – 2008-09-19 18:42:30

1

這是最好的方式來做到這一點,如果你的課程非常輕量級 - 我的意思是它不是很昂貴的複製它。

該方法的一個副作用是它確實傾向於使它更有可能創建臨時對象,儘管這可能取決於編譯器如何優化事物。

對於你想確保不會被複制的更重量級的類(比如說一個大的位圖圖像),那麼把一個像這樣的東西作爲參考參數傳遞是一個好主意,確保不會有任何臨時對象被創建。

總的來說,簡化語法和使事情變得更加直接的事情可能會在表達式中創建更多臨時對象的副作用,只是在設計更重量級對象的接口時應該記住的事情。

2

Rob Walker的示例之間的區別稱爲返回值優化(RVO),如果您想要Google的話。順便說一下,如果你想確保你的對象以最有效的方式得到返回,那麼使用shared_ptr在堆上創建對象(即通過new),並返回一個shared_ptr。指針返回並且引用計數正確。