2010-12-27 6 views
3

テストプログラムはなぜオブジェクトを宣言するときにコンストラクタも代入演算子も実行されませんでしたか?

#include <iostream> 
using namespace std; 

class A 
    {public: 
     A(): I(0) {cout << "default construcot" << endl; }; 
     explicit A (int i): I(i) {cout << "another construcot" << endl; }; 
     A (const A& a): I(a.I) {cout << "copy constructor" << endl; } 
     A& operator = (const A& a) 
      {cout << "assignment operator" << endl; 
      if (this == &a) return *this; 
      I = a.I; 
      return *this; 
      } 
     void show() {cout << I << endl; }; 
    private: 
     int I; 
    }; 

int main() 
    {A a = A(1); 
    A b; 
    b = A(2); 
    a.show(); 
    b.show(); 
    return 0; 
    } 

出力

another construcot 
default construcot 
another construcot 
assignment operator 
1 
2 

ショーで、 '' 'B' とは異なり、そのオブジェクトは、代入演算子の実行せずに(1) "直接" から構築しました。しかしコピーコンストラクタも実行されていませんでした。どうして?この場合、代入演算子を強制的に実行する方法はありますか?私は

A a (1); 

を書いた場合、私はそのような行動を期待しますが、私は最初のケースとは異なりする必要が

A a = A(1); 

をしたいです。か否か?

(私はAから派生したクラスBがあり、A = B(...)のような宣言を処理するために、Aの代入演算子をしたい時に実際には、問題が表示されます。)

+0

コンパイラライターは、代入演算子/コピーコンストラクタへの不要な呼び出しを取り除くのに十分にスマートでした。 – DumbCoder

+0

なぜあなたは自己への割り当てを気にしますか?(この==&a) 'クラスはそれほど単純ではありません。それがもっと複​​雑な場合は、コピーとイディオムを使用する必要があり、それでテストは冗長になります。 –

答えて

3

なぜ

標準は、コンパイラがコピー工事を離れて最適化することができます。 NOT宣言の一部であるため、代入が行われます(最適化が行われなかった場合は一時オブジェクトが生成され、仮のコピー構成がaになります)。

この場合、代入演算子を強制的に実行する方法はありますか。

これはコンパイラによって異なります。しかし、私はあなたがこれを強制することができるものは知らない(しかし、私はそれをオフにしようとしたことはありません)。コンパイラが行っているすべての最適化を無効にしてみてください。

私が次のように書くと、このような動作が期待されます。A(1);

標準では、このバージョンに最適化できることが明示されています。

私はAから派生したクラスBがあり、A = B(...)のような宣言を処理するために、Aの代入演算子をしたい。)

あなたはBをスライスすることを行う場合と、 BオブジェクトのA部分を代入するだけです。
リファレンスを使用しますか?

A const& a = B(); 
+0

まあ、私は理解...私は参照またはポインタを使用することができます...しかし、誰かが私のクラスを使用し、それから "正常な"動作を期待すると思うことができます。たぶん私は間違った方法ですべてをやろうとしています。おそらく私は将来アドバイスを求めるでしょう。 – Nick

1

なぜ?なぜなら、コンパイラは自由に実行でき、ほとんどの場合です。

あなたはそれを強制できますか?特許

6

この

A a = A(1); 

はこれに等価ではない:第二場合=

A a; 
a = A(1); 

最初のケースで=がオペレータないが、演算子です。最初の文では、初期化構文です。コンパイラはコピーコンストラクタを呼び出すことができますが、言語(RVO、例外スローなど)によって許可されている場所の1つとして最適化できます。

1

コンパイラが基本的にコピーの構造を基本的に削除し、最初の形式が初期化構文であると明示的に定義されています。しかし、実際の派生インスタンスで呼び出すと、この動作が削除されるため、プログラムの正確性に影響する可能性があります。

1

私はそれが標準で保証され、A a(1);A a = 1;が厳密に同じものであると思います。

関連する問題