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」とは異なり、オブジェクト「a」が代入演算子を実行せずに「直接」A(1)から構築されたことを示しています。しかし、コピーコンストラクターも実行されませんでした。なんで?この場合、代入演算子を強制的に実行する方法はありますか?私が書いたらそのような行動を期待したでしょう

A a (1);

でも私はしたい

A a = A(1);

これは最初のケースとは異なる必要があります。か否か?

(実際、問題は、Aから派生したクラスBがあり、Aの代入演算子にA a = B(...)のような宣言を処理させたい場合に発生します。)

4

5 に答える 5

6

これ

A a = A(1);

これと同等ではありません:

A a;
a = A(1);

2番目のケース=は演算子であり、最初のケース=は演算子ではありません。最初のステートメントでは、初期化構文です。コンパイラーはコピーコンストラクターを呼び出す場合がありますが、言語(RVO、例外スローなど)で許可されている場所の1つであるため、最適化できます。

于 2010-12-27T19:20:40.120 に答える
3

なぜ

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

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

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

私が次のように書いた場合、私はそのような振る舞いを期待していました。

この規格では、バージョンをこれに最適化できると明示的に規定されています。

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

これを行う場合は、Bをスライスし、BオブジェクトのA部分を割り当てるだけです。
参照を使用しますか?

A const& a = B();
于 2010-12-27T19:31:21.430 に答える
1

なんで?コンパイラはそれを自由に行うことができ、ほとんどの場合そうするからです。

強制できますか?いいえ。

于 2010-12-27T19:18:02.680 に答える
1

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

于 2010-12-27T19:29:22.557 に答える
1

私は願っA a(1);ています、そしてA a = 1;厳密に同じことです、それは標準によって保証されています。

于 2010-12-27T21:36:10.660 に答える