2015-02-24 53 views
-1

簡易程序的意外行爲:與構造

#include <iostream> 

using namespace::std; 


class X { 
    public: 
     X() { 
      cout << "Default Constructor called\n"; 
      i = 0; 
     } 


     X(int i) { 
      cout << "Parameterized Constructor called\n"; 
      this->i = i; 
     } 
     X(const X& x) { 
      cout << "Copy Constructor called\n"; 
      i = x.getI(); 
     } 
     ~X() { 
      cout << "Destructor called\n"; 
     } 
     int getI() const { 
      return i; 
     } 
     X func() { 
      cout << "Entered func\n"; 
      X x(2); 
      return x; 
     } 
    private: 
     int i; 
}; 

int main() { 
    X x1; 
    X x2 = x1.func(); 
    cout << "Returned from func\n";  
} 

它輸出以下:

Default Constructor called 
Entered func 
Parameterized Constructor called 
Copy Constructor called 
Destructor called 
Returned from func 
Destructor called 
Destructor called 

我的問題是,經過了「從FUNC返回」被打印出來,沒有構造函數被調用時創建實例x2。我實際上期望在實例化x2時會調用一個拷貝構造函數,因爲如果我們做了類似的工作,它會是X x2 = x1;

回答

2

我最初錯誤地認爲原因是RVO,所以我保留原始答案在下面。

你的程序打印預期。請注意,打印「返回功能」您調用它並將返回的值分配給x2。所以打印的順序是正確的:它首先實例x,因此參數化的構造函數調用,然後將其複製到x2,因爲它從功能上退出,然後調用的x析構函數,它不再需要了,那麼實際上退出從函數中,只有它到達您的打印語句。

老的回答如下


你觀察什麼是返回值優化。

返回值優化,或者乾脆RVO,是一個編譯器優化 技術,涉及消除創建 臨時對象持有函數的返回值。 1在C++中,這是被允許改變所得 程序的可觀察行爲尤其顯着 。[2]

一般而言,C++標準允許編譯器執行任何 優化,提供生成的可執行呈現相同 觀察行爲好像(即假裝)的 標準的所有要求已經實現。這通常被稱爲 「as-if規則」。[3]術語返回值優化是指在C++標準,走得更遠比 一個 特約條款「作爲假設」規則:實現可省去從一個return語句導致 複製操作,即使拷貝構造函數有副作用 效果。[4]

this wikipedia article,它有一個例子,這是非常類似於你

+0

請解釋清楚。我不知道優化是什麼。請給我一次這種食物。 :( – 2015-02-24 06:38:21

+0

按照我發佈的鏈接,我不能解釋比維基百科:) – Ishamael 2015-02-24 06:39:12

+1

嗯......好的。謝謝。我愛你。 – 2015-02-24 06:39:22