[英]C++: Return by reference to return by value
我一直在閱讀邁爾斯的書,並通過引用/指針和值返回來查看項目。 關鍵是,如果我們的函數是這樣的:
ClassA& AddSomething(ClassA classA)
{
ClassA tempClassA;
//... do something on tempClassA
return tempClassA;
}
這不起作用,因為我們返回對堆棧上創建的對象的引用,並且現在函數已經完成。
他給出了兩個解決方案
作為對象返回:
ClassA AddSomething(ClassA classA) { ClassA tempClassA; //... do something on tempClassA return tempClassA; }
現在,如果我要這樣做:
ClassA obj1;
ClassA obj2 = AddSomething(obj1);
我現在的困惑是,在執行此行時:
所以基本上,傳遞給復制構造函數的是對tempClassA的引用(在函數內部的堆棧中創建)或對tempClassA副本的引用。
另外,我的另一個問題是,我已經讀過,如果我得到函數局部變量的引用,那么本地變量將不會被刪除。 例如,
ClassA & classRef = AddSomething(obj1);
在這種情況下,如果AddSomething()返回引用,則classRef不指向已刪除的引用,因為將保留本地變量。 我理解正確嗎?
在最壞的情況下,你是對的: tempClassA
的副本被傳遞給復制構造函數。 但是允許編譯器消除該副本並從tempClassA
構造結果。 這稱為“返回值優化”或RVO。 我不知道沒有這樣做的編譯器。
當按值返回對象時,會發生兩個副本:一個從局部變量返回到返回值,另一個從返回值返回到目標對象。 然而,實現允許一個的Elid或兩個副本; 這在第一種情況下稱為返回值優化 (RVO),在第二種情況下稱為復制省略 。
Object some_function() {
return Object(); // copy Object() into return value; candidate for RVO
}
Object another_function() {
Object obj;
return obj; // copy obj into return value; candidate for NRVO
}
Object result = some_function(); // copy return value into result; candidate for copy elision
上面的第二個函數是RVO的細化類型的候選函數,稱為命名返回值優化; 最簡單的RVO形式僅適用於構造返回值的返回語句。
關於第二個問題,生命周期擴展僅適用於對value返回的對象的const引用; 第二個問題中的代碼不會延長任何對象的生命周期。 有關更多詳細信息,請參閱返回臨時對象和綁定到const引用 。
您永遠不能通過引用返回函數局部變量。 即使您使用const引用捕獲返回的值,它也不會工作,如下所示:
const ClassA& classRef = AddSomething(obj1);
因為如果AddSomething通過引用返回本地對象,那么在classRef引用它時,它將是對不存在的對象的懸空引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.