5

A a1(5)の違いは何ですか。およびAa2= A(5)?どちらの作品も、どちらか一方のプロジェクトで方法2を使っていて、方法1に変更すると修正されるバグがあったので、違いを知りたいです。よろしくお願いします。

class A {
public:
    int val;
    A() : val(0) {}
    A(int newVal) : val(newVal) {}
};

int main()
{
    A a1(5);  // method 1
    A a2 = A(5); // method 2
}
4

2 に答える 2

8
A a1(5);  // method 1
A a2 = A(5); // method 2

最初のものは直接初期化と呼ばれ、2番目のものはコピー初期化と呼ばれます。

コピーコンストラクターにアクセスできないようにした場合、または/および次のように定義しない場合、2番目のものはコンパイルされません。

class A {
public:
    int val;
    A() : val(0) {}
    A(int newVal) : val(newVal) {}
private:
    A(A const&);  //the second one will not compile
};

これで、2番目のものはコンパイルされません。どちらの場合もコンパイルされないことに注意してください。

  • コピーコンストラクターが定義されているが、アクセスできない場合(またはのいずれprivateprotected)。
  • コピーコンストラクターが宣言されているが、定義されていない場合。
于 2012-06-22T04:24:32.143 に答える
1

厳密に言えば、あなたの質問を読んで、私はあなたがこれらの2つの例を提供することを期待しました

A a1(5);  // method 1
A a2 = 5; // method 2

1つ目は直接初期化です。2つ目は、コピーの初期化です。

あなたがあなたの質問で提供した例は、実際にはすでに2つの違いを示しています:)

直接初期化は、適切なコンストラクターを見つけて使用することにより、シングルステッププロセスとしてターゲットオブジェクトを直接初期化します。コピー初期化は、概念的には2段階のプロセスです。最初に変換コンストラクターによって型の一時オブジェクトをA構築し、次にコピーコンストラクターを使用して宛先オブジェクトにコピーします。つまり

A a2 = 5;

実際には次のように機能します

A a2 = A(5);

そして、それは実際に違いを徹底的に説明しています。

2番目のバリアントの2段階の構造も、概念的なものです。コンパイラーは、最初のバリアントとまったく同じように機能するように、2番目のバリアントを最適化することが許可されています(そして最適化されます)。それらは中間の一時オブジェクトを排除し、直接初期化を実行します。

于 2012-06-22T04:26:22.443 に答える