2012-01-10 60 views
5

可能重複:
Why copy constructor is not called in this case?複製構造不調用

考慮下面的示例程序:

#include <iostream> 

using namespace std; 

class sample 
{ 
    private: 
     int x; 

    public: 
     sample(int a=0) : x(a) 
     { 
      cout << "default ctor invoked\n"; 
     } 

     sample(const sample& obj) 
     { 
      cout << "copy ctor invoked\n"; 
     } 

}; 

int main() 
{ 
    sample s2 = sample(20); //Line1 
    sample s3 = 20; //Line2 

    return 0; 
} 

Line1,第一sample類的構造函數被調用explicitly與參數20.然後我的預期要調用的複製構造函數來初始化s2。

在Line2中,首先使用參數20首先調用sample類的構造函數implicitly。這裏我也希望調用copy構造函數來初始化s2。

在這兩種情況下,複製構造函數都不會被調用?這是爲什麼發生?我相信,我對複製構造函數的調用有所瞭解。有人能糾正我在哪裏出錯嗎?

+0

這是預期的 - 讓我試試並找到一個好例子 – 2012-01-10 04:42:14

+0

在某些情況下,可以省略對複製構造函數的調用。 – 2012-01-10 04:45:12

+0

@ R.MartinhoFernandes:在某些情況下。但s2和s3必須以某種方式初始化。如何在沒有調用copy ctor的情況下完成? – 2012-01-10 04:46:16

回答

8

這是預期的。它被稱爲copy elision

您的期望是正確的,但他們在C++(用於性能)中做了一個例外,它允許編譯器將您的表達式視爲一個實例的直接初始化,同時繞過複製構造函數。

+0

對於第一個例子是的,編譯器可能決定做複製elision或不這樣做。但是我認爲在第二行中,'sample s3 = 20;',那麼編譯器*必須*只調用'int'構造函數。我想我問的是「在這兩種情況下複製elision *可選*」? – 2012-01-10 04:51:09

+1

如果複製構造函數不可訪問(即'private')或被刪除,那麼它們都不會工作。所以它不是直接初始化。 – 2012-01-10 04:59:06

+0

它們都需要複製初始化。兩者相當於樣本s(樣本(20));'。你可以通過在拷貝ctor私有後編譯來證明這一點。從不需要複製elision。它被編譯器優化的標準*所允許*。它是否被刪除取決於你的編譯器。 – justin 2012-01-10 05:01:19

0

在第一行中它不會調用複製構造函數,因爲您不復制對象。您正在將一個對象分配給其他對象。 C++提供執行淺拷貝的default =運算符。這是隱式調用的。爲右手對象調用構造函數,爲左手對象調用默認構造函數。之後,調用default =運算符。

對於第2行,它使用構造函數,它接受您定義的int參數。它實際上是轉換器構造函數,因爲它需要一個整數並創建類的對象。這就是爲什麼C++使用它作爲轉換器的構造函數,並且當你嘗試給你的對象分配一個整數時,C++會明確地調用這個轉換器的構造函數。

我希望這可以幫助你理解。

+0

Cemal:我認爲你對Line1的解釋不正確。正如我從給出答案和評論的其他人那樣理解的,Line1和Line2都是複製初始化,但編譯器通過阻止調用複製構造函數來優化它以直接初始化。 – 2012-01-10 07:31:58

+1

是的你有權利。一般來說,當你使用=運算符時,它使用拷貝構造函數,但是我沒有根據提問者的要求來實現。正如你所說,我沒有考慮編譯器優化,直接思考。感謝您的警告 – 2012-01-10 07:34:45