0

ムーブ コンストラクターとムーブ代入演算子が宣言および定義されたツリー クラスがあります。

コンパイラがコピー コンストラクターを合成する必要性を感じてから、std::unique_ptrプライベート メンバーがあると不平を言うのはなぜでしょうか?

これは逆効果のようです。コンパイラは、本体のない、または単に定義されていない隠しコピーと割り当てが、コピーの試行を防ぐためであることを認識しないでstd::unique_ptrください。

また、コピー コンストラクターと代入演算子を空の本体で宣言および定義すると、コンパイラーが満足するのはなぜでしょうか?

このクラスを使用してコードを作成および構築し続ける場合、これは懸念の原因になりますか?

追加:

  1. ソースコードのエラーがないのでソースコードはありません...これは
    ソースコードの存在を必要としない質問です。

  2. コピー コンストラクターが非公開の場合、コンパイラーが不平を言うので、それらを公開しました。再び非公開にし、コンパイラがヒックアップするかどうかを確認します。

  3. Visual Studio 2012 Professional IDE とそれに関連するコンパイラを使用しています。

移動コンストラクターが存在するときにコンパイラーがコピーコンストラクターを生成するのはなぜですか? 特にコピーコンストラクターが最初に定義されていない場合は、直感に反するようです。

追加の質問:

Visual Studio 2012 は、コンストラクターまたは代入演算子の = delete 宣言をサポートしていないようです。宣言を非表示にすると、コード全体でコンパイラーが泣くようになります。私は今何をしますか?何もしないコピーコンストラクターを宣言するのは悪い考えであることに同意します(以下)。他にどのようなオプションがありますか?

小さな例が本当に必要な場合は、ここにあります。私のコンパイラは = delete をサポートしていません

class Tree{
    class TreeNode{
         "declaration of unique_ptr, cstrs, move cstrs, hidden copy cstrs"
    };
public:
     "declaration of unique_ptrs, cstrs, move cstrs, copy cstrs <----- compiler 
      complains if hidden"
};

これで boost::variant を使用する

4

2 に答える 2

2

コピー コンストラクターがない場合、コンパイラは生成を試みます。デフォルトのコピー コンストラクターはかなり馬鹿げているので、クラスの一部につまずいても驚くことではありません。

空のコンストラクターを定義すると、何もしないコピー コンストラクターが得られます。これにより、コンパイラーが生成したはずのコンストラクターが置き換えられ、問題が回避されます。

于 2013-03-28T12:04:25.250 に答える
1

コンパイラがコピー コンストラクターを合成する必要性を感じてから、std::unique_ptrプライベート メンバーがあると不平を言うのはなぜでしょうか?

標準ライブラリが非準拠であり、削除されたコピーコンストラクターではなくプライベートを宣言しない限り、そうすべきではありませんunique_ptr。その場合でも、移動コンストラクターを宣言していない場合にのみ合成する必要があります。

クラスにunique_ptrメンバーがある場合、または移動コンストラクターを宣言する場合は、コピー コンストラクターが削除されたことを通知する必要があります。そして、それをコピーしようとするコードを書いた場合のみ。

コンパイラは、本体のない、または単に定義されていない隠しコピーと割り当てが、コピーの試行を防ぐためであることを認識しないでstd::unique_ptrください。

それは正しい; ただし、合成されたコピー コンストラクターと代入は、定義されていないのではなく、削除されています。

また、コピー コンストラクターと代入演算子を空の本体で宣言および定義すると、コンパイラーが満足するのはなぜでしょうか?

暗黙的に生成される(または生成されない)コードではなく、その(空の)コードをコピーに使用することを明示的に言っているためです。しかし、それは悪い考えです。クラスがコピー可能でない場合は、間違った実行時の動作ではなく、コピーを試みてエラーを生成する必要があります。

于 2013-03-28T12:18:52.103 に答える