2010-05-12 77 views
15

在參考中存儲對象的返回值是否有效?在參考C++中存儲函數的返回值

class A { ... }; 
A myFunction() 
{ 
    A myObject; 
    return myObject; 
} //myObject goes out of scope here 

void mySecondFunction() 
{ 
    A& mySecondObject = myFunction(); 
} 

是否有可能做到這一點,以避免將myObject複製到mySecondObject? myObject不再需要,應該與mySecondObject完全相同,因此從理論上講,只需將對象的所有權從一個對象傳遞給另一個對象就可以更快。 (這也可以使用提升共享指針,但它具有共享指針的開銷。)

在此先感謝。

回答

19

不允許將臨時綁定到非const引用,但是如果您使用const引用,則將臨時的生命週期延長到引用,請參閱this Danny Kalev post about it

簡而言之:

const A& mySecondObject = myFunction(); 
+1

你碰巧知道爲什麼這是不允許的? – Mehrdad 2012-02-17 04:11:00

+0

林不知道,但我猜測,原因是,允許非const引用意味着編譯器將需要確定何時重新分配引用。我認爲這通常被認爲是動態作用域分析的一部分,並未在C++標準中使用。另一方面,在const情況下,只需要確定參考的靜態生命週期。這種分析可能已經在其他情況下需要,因此被認爲是可以接受的。 – 2013-08-05 14:35:20

+0

人們也可以注意到,這是一個非常簡單的指針跟蹤功能,可以想象一個更高級的系統。但總的來說,我相信C++想要避免這個問題,並將其委託給程序員。這就是智能指針。 – 2013-08-05 14:37:57

3

這是可能的const引用。

myFunction按值返回,以便返回值是一個臨時對象。您可以將臨時綁定到const引用,並將臨時的生命週期擴展到引用的生命週期。您不能將臨時綁定到非const引用(不幸的是)。

返回值myFunction可能是副本myObject。另一方面,複製構造函數elision(在這種情況下也稱爲「命名的返回值優化」)允許編譯器將myObject直接構造到myFunction的返回值(可能位於調用代碼堆棧的某處)的臨時值中。如果是這樣,那麼當myObject超出範圍時,該對象實際上不會被銷燬。優化通常被實現 - 例如GCC(通常是?)即使沒有任何優化標誌也可以實現。

拷貝構造函數省音還允許編譯器避開所有的複製,如果你做的事:

A mySecondObject = myFunction(); 

這既需要法律類型的副本構造函數省音的應用程序:(1)從函數返回一個命名的值,和(2)從臨時初始化對象。

5

您可能會對return-by-value optimization感興趣,很多編譯器會避免調用複製構造函數。

+0

這是我正在尋找的那些想法之一。我無法訪問該頁面,但我認爲https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization會類似。 – konsolebox 2017-11-16 11:05:40