3

MFC の CPoint クラスを使用しています。明示的に定義された代入演算子またはコピー コンストラクター (AFAIK) はありません。それでも、これは機能します:

C点 p1(1, 2), p2;
p2 = p1; // p2 は p1 と等しくなります

コンパイラが代入演算子を生成したため、これは自動的に機能していると思います。正しい?

もしそうなら、これが予期せぬことをしていないと確信できますか? この場合、CPoint は非常に単純なので、すべて問題ないと思いますが、一般的にこれは少し心配です。行う方が良い形式ですか:

p2.SetPoint(p1.x, p2.x);

-cr

4

7 に答える 7

4

これは安全です-代入演算子が提供されることを意図されていなかった場合、MFC設計者はそれが利用できないことを確認できたはずです(たとえば、それをプライベートにすることによって)。

IIRCコンパイラはメンバーごとのコピーを実行するため、このようなPODを含むクラスの場合、問題は発生しません。メモリを割り当て、operator =をオーバーライドしてディープコピーを実行することを怠るクラスがある場合、混乱する可能性があります。

FWIWしばらく前に、コンパイラーができることとできないことについて質問しました。

C++コンパイラがoperator==とoperator!=を定義しないのはなぜですか?

いくつかの答えは興味深い読み物になります。

于 2008-12-19T21:40:08.263 に答える
3

デフォルトのコピーコンストラクターを検索します。

http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

これはCPointの特別なことではありません。

于 2008-12-19T21:41:38.323 に答える
1

クラスが「単純」である場合、コンパイラーによって生成された代入演算子が機能します(メンバーごとにコピーします)。より高度なロジックを必要とするメンバーがいくつかある場合(たとえば、オブジェクトがプライベートバッファーであると期待するものへの内部ポインターを維持している場合)、コンパイラーによって生成された代入演算子に問題が発生します。CPointポイントのx座標とy座標を格納するだけなので、問題が発生することはありません。

于 2008-12-19T21:38:23.040 に答える
0

私はMFCを知りませんが、それを推測することができます(あるいは):

  • CPointには、定義された代入演算子があります(したがって、コンパイラーによって生成されません)、または
  • コンパイラー生成の代入演算子は、メンバーがスタック割り当てされている場合に機能するため、メンバーごとにコピーします。
于 2008-12-19T21:38:33.023 に答える
0

組み込みのコピー代入演算子は、コピー代入演算子を使用して各メンバーを順番にコピーするだけです。ドキュメントを見なくてもCPointにとって安全だと思います(理由:そうでなければ、もちろん独自の実装を提供します)。そのポイントクラスには2つのメンバー(xとy)が必要であり、それらは単なるfloat(または使用内容によってはint)です。

メンバーの値だけがコピーされるので、それは「浅いコピー」だと言う人もいます。ポインターメンバーがある場合は、ポインターが指すオブジェクトではなく、ポインター値がコピーされます。

于 2008-12-19T21:41:04.220 に答える
0

CPointのような単純なデータオブジェクト(Visual Studioのインストールに含まれているMFCソースからわかるように、いくつかの便利な関数が追加されたWin32 POINT構造体です)の場合、コンパイラーで生成された代入演算子を使用しても問題はありません。

しかし、すでに述べたように、デフォルトの代入演算子は浅いコピーであり、構造体にポインターが含まれている場合(または代入演算子を定義せずにポインターを含む構造体が含まれている場合)に問題が発生します。CPointはその説明に適合しないため、安全です。

于 2008-12-19T21:47:37.047 に答える
0

はい。クラスにメソッドを定義しない場合operator=、コンパイラは、クラス内のフィールドのビットごとのコピーを行うだけのメソッドを生成します。私が思い出したように、CPointは単に{int x; int y}であるため、ビットごとのコピーで問題ありません。

于 2008-12-19T22:02:16.563 に答える