0

假設編譯器中沒有返回值優化。
在C++中,當函數中的對象return-by-vaule時,真正的步驟在下面,我正確嗎?完全,第三次調用構造函數。按值返回是否調用複製構造函數或複製賦值運算符?

本地(正常constuctor) - >溫度(拷貝構造函數)--->(拷貝構造函數或複製assignemt運營商)

  1. 創建一個本地的對象,在這裏它調用正常的構造函數;
  2. 使用本地對象創建一個臨時對象,在這裏它調用複製構造函數;
  3. 分配臨時對象實物以外(一),在這裏它調用拷貝構造函數(情形),或者拷貝賦值運算符(情形2)
class Name{...}; 

Name func(){ 
    // ... 
    Name local; 
    return local; 
} 

案例1:

Name outside = func(); // call copy constructor? 

case2:

Name outside; 
outside = func(); // call copy assignment operator? 

如果我在第一部分是正確的,那麼如果啓用了返回值optimizaiton?

+0

我建議你用一些輸出語句編寫一個快速程序並查看。這似乎取決於所涉及的變量以及編譯器將作爲優化的一部分作出的決定。例如,在某些情況下,可能會採取行動而不是複製或建設。 –

+0

@ M.M是的,正確的。 – Edison

+0

請注意,RVO並不是常規意義上的優化,這種做法可以更快地完成相同的任務,而是在語義上成爲語言的一部分。編譯器可以不運行復制/移動構造函數,即使它們有副作用,所以輸出可能會有所不同。 – sp2danny

回答

0

這個問題讓我覺得,所以在這個意義上,這是一個很好的問題。我在「Debug」模式下運行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。

返回值優化將取決於編譯器和設置。例如,當我在發佈模式下構建並運行時,沒有對拷貝構造函數的調用,指示臨時對象僅用於調試模式。 (我不是這方面的專家。)

+0

thx!有用。這就是我要的 – Edison

1

在C++中複製elision /返回值優化允許它跳過調用一個副本構造函數。

第1種情況,您在回報中使用複製構造並在「外部」構建實例。這些中的任何一個或兩個都可以被忽略。 即使C++可以產生可測量的副作用,也可以使用這些函數調用 - 不適用as-if規則。案例2您正在使用賦值運算符將您的值存入變量「outside」中,這樣​​的not-as-if複製elision異常不適用於此處。所以,你會得到一個賦值操作符的調用,除非編譯器可以安全地忽略它,因爲它沒有副作用。在後一種情況下,編譯器可以自由選擇,但根據定義,很難說出發生了什麼。

相關問題