24

たとえば、クラスを宣言したいが、クライアントがコピー コンストラクター (またはコピー代入演算子) を使用できないようにしたい

次の 2 つのどちらも、コピー コンストラクターの使用を許可しません。

1.

class Track
{
public:
  Track(){};
  ~Track(){};
private:
  Track(const Track&){};
};

2.

class Track
{
public:
  Track(){};
  ~Track(){};
  Track(const Track&)=delete;
};

これらの方法の 1 つは、他の方法よりも「より正確」ですか、それとも同等ですか? 副作用はありますか?

//Does not compile with both the above ways
int main()
{
  Track l;
  Track p(l);
}
4

7 に答える 7

19

それを非公開にすることは、それを行う「古い」方法です。コンストラクターは引き続き存在しますが、プライベートであり、別のクラス メンバー関数内からのみ呼び出すことができます。

= delete コンストラクターを削除します。これはコンパイラによって生成されたものではなく、単に存在しません。

おそらく、= deleteあなたが望むものです。(ただし、すべてのコンパイラがこの構文をまだサポートしているわけではないため、移植性が懸念される場合は...)

于 2013-05-26T10:26:16.127 に答える
8

コピー コンストラクターを宣言しても、クラスprivateのメンバー関数はそのTrackクラスのインスタンスをコピー構築できますが、それを削除すると、単にそのオブジェクトのコピー構築が禁止されます。

C++11 では、コピー コンストラクターを削除することは、クラスがコピーできないという事実を表現する正しい方法ですTrack(もちろん、 のメンバー関数または のフレンドにオブジェクトTrackをコピー構築させることが理にかなっている場合を除きTrackます) 。 .

于 2013-05-26T10:25:56.257 に答える
5

コンストラクターを非公開にすることは、ユーザーがコンストラクターを使用できないようにする唯一の方法だったため、古い C++ では基本的に「ハック」でした。メンバー関数をdelete特別にする機能は、C++11 でのみ導入されました。これは、クラスをコピーできないことを示すより適切で慣用的な方法です。意図がはっきりしているからです。

プライベート コンストラクターには、その使用を完全に禁止する以外の用途があります (たとえば、静的クラス メンバー関数によって呼び出される場合があります)。したがって、コンストラクターをプライベートにするだけでは、意図がうまく伝わらず、結果として生じるエラーもあまり明確ではありません。

于 2013-05-26T10:26:21.150 に答える
0

最初のアプローチは、クラス自体が自分自身をコピーすることを妨げません。これを解決する従来の方法は、コピー コンストラクターを非公開として宣言し、実装ないままにすることです。

ただし、これに関する問題は、意図が明らかでない可能性があることです。コードを読んだ人は、孤立した宣言が存在する理由を理解できず、誤って削除する可能性があります。boost::noncopyableBoost を使用できる場合は、コメントを非公開で継承するのと同様に、コメントが役立ちます。

2 番目のアプローチは意図を明確にするものであり、C++11 を使用できる場合に好まれる方法です。

于 2013-05-26T10:26:38.483 に答える
0

最初のソリューションは、コピー コンストラクターが非公開であり、使用されないことを読者に伝えます。2 番目のソリューションは C++11 でのみ有効です。このため、プライベート プロパティを使用して、より移植性が高く読みやすい実装が最初になると思います。

于 2013-05-26T10:27:24.960 に答える