[英]Does a return by value call the copy constructor or the copy assignment operator?
假設編譯器中沒有返回值優化。
在c ++中,當對象按函數返回值時,真正的步驟如下,我是否正確? 總共,第三次調用構造函數。
本地 (普通構造函數)-> 臨時 (副本構造函數)---> 外部 (副本構造函數或副本Assignemt運算符)
class Name{...};
Name func(){
// ...
Name local;
return local;
}
情況1:
Name outside = func(); // call copy constructor?
情況2:
Name outside;
outside = func(); // call copy assignment operator?
如果我在第一部分中是正確的,那么如果啟用了返回值優化怎么辦?
這個問題讓我思考,因此從這個意義上講,這是一個好問題。 我在Visual Studio C ++ Express 2010上的“調試”模式下運行了以下測試代碼。
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(int arg) { val = arg; cout<<"Constructor (normal): "<<val<<endl; }
Foo(const Foo& ref) { val = ref.val; cout<<"Copy constructor: "<<val<<endl; }
const Foo& operator=(const Foo& rval)
{
cout<<"Assignment operator from object "<<rval.val<<" to object "<<val<<endl;
val = rval.val;
return *this;
}
int val;
};
Foo process() {Foo t(2); return t; }
int main()
{
Foo a(1);
a = process();
system("pause");
return 0;
}
結果:
Constructor (normal): 1 Constructor (normal): 2 Copy constructor: 2 Assignment operator from object 2 to object 1 Press any key to continue . . .
因此,案例2似乎是正確的。 構造外部“ Foo”之后,將在函數內部構造“ Foo”對象。 然后,使用復制構造函數創建另一個對象,最后調用賦值運算符將結果復制到對象a。
返回值的優化將取決於編譯器和設置。 例如,當我在發布模式下構建和運行時,沒有調用復制構造函數,這表明該臨時對象僅用於調試模式。 (我不是這個主題的專家。)
C ++中的復制省略/返回值優化允許它跳過調用復制構造函數。
情況1,您在返回中使用副本構造並構建“外部”實例。 這些都可以被忽略。 C ++允許ellide即使他們有可衡量的副作用,這些函數調用-無作為,如果規則適用。
情況2,您正在使用賦值運算符將您的值添加到變量“外部”中,“按原樣復制”省略例外不適用於此處。 因此,您將獲得一個賦值運算符調用,除非編譯器由於沒有副作用而可以安全地退出它。 在后一種情況下,編譯器可以自由選擇,但是根據定義,很難告訴您發生了什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.