2012-03-13 9 views
0

可能な二重にコピーコンストラクタについて困惑している:次のコードで
Why copy constructor is not called in this case?私はC++

、私は三つの変数、A1、A2およびA3を構築しました。 C++プライマーp.476の例があります

は:

string empty_copy = string();//copy-initialization 

誰も私が説明するのに役立つことができますあります

1)なぜA1とA2は、コピーコンストラクタによって構築されていないと

2 )私のコードの初期化a2と本のempty_copyの違いは何ですか?

ありがとうございます!

#include<iostream> 
using namespace std; 
class A{ 
public: 
    A(){} 
    A(int v){} 
    A(const A&x){ 
     cout<<"copy constructor"<<endl; 
    } 
}; 
A generateA(){ 
    return A(0); 
} 
int main(){ 
     cout<<"First:"<<endl; 
     A a1=generateA(); 

     cout<<"Second:"<<endl; 
     A a2=A(0); 

     cout<<"Third:"<<endl; 
     A a3=a1; 
    return 0; 
} 

アウトプットは(win7の2010年のVisual Studioの下でUbuntu10.10でのG ++)である:

First: 
Second: 
Third: 
copy constructor 

答えて

6

これは、Return value optimizationにコピーの省略です。
コンパイラは、そのような最適化を適用してコピーの生成を最適化できます。

A a1=generateA(); 
A a2=A(0); 

上記の両方の場合、コンパイラは戻り値を保持するために作成される一時オブジェクトの作成を排除できます。

A a3=a1; 

a3このの構築のために使用される既存の名前付きオブジェクトa1を含み、コンパイラがしなければならないし、最適化することはできませんコピーコンストラクタ呼び出しを必要とします。

編集:コメントのQに答えるには

あなたはコンパイル時に次のオプションを使用して、この最適化を適用しないようにコンパイラに指示することができます

GCCの場合:

/Od 
+0

また、*一時的な初期化による* elionコピー。したがって、両方の種類の溶出が使用される。 –

+0

ありがとう!ところで、最適化を無効にする方法はありますか? –

+0

@ user1265982:はい。詳細については、更新された回答をご確認ください。 –

1

    -fno-elide-constructors 
    

    MVSCについて

  1. コピーコンストラクタはa1a2では使用されません。いずれの場合も、intを渡しているため、コンパイラは定義したコンストラクタA(int)を使用しています。

  2. 帳からあなたと例との違いは、あなたのケースでは、既存のを使用している間の本は、スタック(string())上のインスタンスを作成し、そのため空のコピーを取得していることですインスタンス(a1)。どちらも初期化にコピーコンストラクタを使用しています。

1

a1を初期化すると、整数ファクトリ(ファクトリ関数で与えられます)があります。 a2の場合は整数も渡します。 a3については、a3 = a1と言います。コピーコンストラクタが定義されているので、これはa3(a1)と解釈され、呼び出されます。