18

当社のコーディング規約では、「(偶発的な)コピーを防ぐ方法を知っておく」ように言われています。

これが何を意味するのかはよくわかりませんが、必要がない場合はクラスのコピーを停止する必要があることを意味していると仮定します。

私が考えることができるのは次のとおりです。

  1. クラスのコピー コンストラクターをプライベートにします。
  2. クラスの代入演算子 (operator=) を非公開にします。
  3. クラスのコンストラクターを明示的にします (誤った変数を使用してクラスが作成されるのを防ぐため)。
  4. メモリ割り当てを実行し、コピーが必要なすべてのクラスについて、コピー コンストラクターと代入演算子が浅いコピーではなく深いコピーを実行することを確認します。

私は正しい軌道に乗っていますか?見逃したものはありますか?

4

5 に答える 5

21

はい、代入演算子とコピー コンストラクターを非公開にすると、標準メソッドを使用してオブジェクトのコピーを作成できなくなります (ただし、オブジェクトのコピーが本当に必要な場合は、たとえば、ディープ コピーを実行する Copy() メソッドを実装できます)。 .

boost::noncopyableを見てください。

更新(Tal Pressmanに関連):

...これらのことを認識し、意図しないオブジェクトを誤ってコピーしないように注意する必要があります。

うーん、偶発的なコピーは代入演算子またはコピー コンストラクターのいずれかを使用して実行されると思います。したがって、それらを非公開にすることは実際には理にかなっています。オブジェクトのコピーがコストのかかる操作である場合、コピーは明示的でなければなりません。他の開発者は意図せず間接的にコピー操作を呼び出すことができ、コンパイラはこれが禁止されていることを彼に通知します。

于 2009-08-27T09:34:18.093 に答える
11

ブーストを使用している場合、クラスがコピーされないようにする最も簡単な方法は、クラスをnoncopyableから派生させることです。

#include <boost/noncopyable.hpp>

class Foo : private boost::noncopyable
{
}

コピー コンストラクターと代入演算子を手動でプライベートにするよりも意図が明確になり、同じ結果が得られます。

于 2009-08-27T09:31:23.060 に答える
11

あなたのコーディング標準が「(偶発的な)コピーを防ぐ方法に注意してください」と述べている場合、クラス自体からのコピーを防ぐことについて話しているだけではなく、不要な/偶発的なコピーのパフォーマンスへの影響について話していると思います。クラスを使用しています。

C++ を初めて使用する人のコードでパフォーマンスが不必要に浪費される主な原因の 1 つは、通常は一時的なコピーによる不必要なコピーです。コンパイラは、いつ一時変数が必要でないかを判断する能力がますます向上しています ( Konrad のコメントのおかげで、"速度が必要ですか? 値による受け渡し"を参照してください)。 C++ で (とりわけ)。私のため、

于 2009-08-27T09:55:20.607 に答える
2

あなたは正しい軌道に乗っています。ブーストを使用したくない場合は、次のことを行うことができます: コピー コンストラクターとコピー代入演算子をプライベートにし、それらを実装しないでください。したがって、インスタンスをコピーしようとすると、コンパイラ エラーが発生します。

于 2009-08-27T09:39:03.993 に答える
0

あなたのリストは、オブジェクトの暗黙的なコピーによる共有ポインタが原因でメモリの同じ領域を複数回削除するなど、エラーを回避するという観点からは見栄えがします。

これも関連していることを願っています。「(偶発的な)コピーを防ぐ方法に注意してください」という文から、「意図しない不必要なコピーに注意する」ことを意味すると解釈できます。これは、パフォーマンスに影響を与える可能性のある状況を意味します。非常に単純な例では、あなたのコーディング規約はあなたが好むべきであることを意味するかもしれません:

std::string text1( "some text" );

以上:

std::string text1 = "some text";

2 番目のケースでは、代入演算子が呼び出されて (コピーの形式で) text1 に「何らかのテキスト」が入力される前に、「何らかのテキスト」を保持するために一時的な文字列が作成されます。明らかにこれは些細な例であり、可能な限りコンストラクターの初期化 (最初の例) を使用することをお勧めします。

于 2009-08-27T10:00:38.490 に答える