1

「C++ オブジェクト モデルの内部」に従って、次の 4 つの条件の少なくとも 1 つが true の場合にのみ、コピー コンストラクターがコンパイラーによって生成されます (プログラマーによって宣言されていない場合)。

  1. コピー コンストラクターが存在するクラスのメンバー オブジェクトがクラスに含まれている場合 (前の String クラスの場合のようにクラス デザイナーによって明示的に宣言されるか、クラス Word の場合のようにコンパイラーによって合成されます)。

  2. クラスが、コピー コンストラクターが存在する基底クラスから派生した場合 (ここでも、明示的に宣言または合成されます)

  3. クラスが 1 つ以上の仮想関数を宣言するとき

  4. クラスが、1 つ以上の基本クラスが仮想である継承チェーンから派生した場合

つまり、コンストラクターだけを持つクラスがある場合、コピーコンストラクターはコンパイラーによって提供されません。

例を見てみましょう:

class test
{
    test(){}
};
int main()
{
    test obj1;       //statement 1
    test obj2(obj1); //statement 2
}

上記のコードは正常に動作します。クラステストに次の行を追加すると、問題が発生します。

test(const test& rhs) = delete;

「= delete」は、コピー コンストラクターが自動的に提供されないようにします。上記の行を追加した後、ステートメント 2 のエラーが表示されますUse of deleted function test::test(const test&)

私の質問は次のとおりです。「Inside C++ Object Model」に従って、上記のクラスのコピー コンストラクターは必要ありません。そのため、(削除を使用して) コピー コンストラクターを生成しないように明示的に言っている場合、エラーが発生するのはなぜですか? コンパイラーが上記のクラスのコピーコンストラクターを必要としないと予想していたので。

gcc バージョン 4.6.3 を使用しています。

4

3 に答える 3

8

クラスをコピー可能にするには、コピー コンストラクターが必要です。独自に作成するか、コンパイラが生成するかは問題ではありません —test a; test b(a);有効な操作であるためには、それが利用可能でなければなりません。

明示的にコンパイラにコピー コンストラクターの削除を強制します。これは、古い「コピー コンストラクターを非公開にする」トリックの新しいバージョンです。コピーを禁止します。したがって、コピーできないことに驚かないでください。許可しないようにコンパイラに指示したためです。

于 2012-06-01T17:47:46.337 に答える
2

暗黙的に生成されたコピー コンストラクターの標準語は[class.copy]/7です。

クラス定義でコピー コンストラクターが明示的に宣言されていない場合は、暗黙的に宣言されます。クラス定義でムーブ コンストラクターまたはムーブ代入演算子が宣言されている場合、暗黙的に宣言されたコピー コンストラクターは削除済みとして定義されます。それ以外の場合は、デフォルト (8.4) として定義されます。クラスにユーザー宣言のコピー代入演算子またはユーザー宣言のデストラクタがある場合、後者のケースは推奨されません。

および[class.copy]/13 :

デフォルト設定され、deleted として定義されていないコピー/移動コンストラクターは、odr で使用されている場合 (3.2)、または最初の宣言後に明示的にデフォルト設定されている場合、暗黙的に定義されます。[注: copy/move コンストラクターは、たとえ実装がその odr-use (3.2、12.2) を省略したとしても、暗黙のうちに定義されます。—終わりの注] 暗黙的に定義されたコンストラクターが constexpr コンストラクター (7.1.5) の要件を満たす場合、暗黙的に定義されたコンストラクターは constexpr です。

そのため、コピー コンストラクターは引き続き に対して生成されtest、ステートメント 2 によって呼び出されます。「C++ オブジェクト モデルの内部」は、コピー コンストラクターが自明ではない場合について話していると思います。

于 2012-06-01T17:48:08.747 に答える
0

この行:

test obj2(obj1)

コピー コンストラクターを呼び出そうとしています。

于 2012-06-01T17:47:36.357 に答える