1

独自のコンストラクタ、デストラクタ、コピーコンストラクタ、コピー代入演算子を実装したクラスがあります。

このクラスには、上記のすべてに含まれるコアメンバーのセットと、一部のメソッドのヘルパーとして追加した「状態変数」のセットがあります。

これらの状態変数は、コンストラクターで初期化されることはありませんが(わざわざ実行しなかったため)、使用される前に初期化されます。

そのため、コピーコンストラクタとコピー代入はそれらに対して何もしません。彼らは私が明示的に欲しいメンバーをコピーするだけです。

  • これは問題になる可能性がありますか?
  • 明示的にコピーされていないメンバー(ところで、これらのメンバーにポインターがない)はどうなりますか?
    • また、コンストラクターで初期化されません
  • これは「隠れた」問題につながる可能性がありますか?

乾杯アンドレ

4

3 に答える 3

3

Can this be a problem?

-使用前にそれらを初期化し、(ポインタの場合)リリースすることを忘れないでください。問題は発生しません。

What happens to members that aren't explicitly copied (btw, no pointers in these members)? they are also not initialized in the constructor

-彼らはゴミを保持します

Can this lead to any "hidden" problems?

-いいえ、注意してください

ただし、どのような場合でもコンストラクターで初期化することをお勧めします。そうすることでエラーをキャッチしやすくなり、オブジェクトが常に完全な状態のままになるためです。たとえば、nullptrポインタをキャッチする方が、ガベージポインタまたは割り当て解除されたオブジェクトへのポインタよりもはるかに簡単です。最初の場合、プログラムはただクラッシュするので(nullポインタの逆参照はUBですが、通常はただのクラッシュです)

また、可能であれば、中間結果を格納するためのローカル変数を作成することをお勧めします。それが単一のメソッドの中間結果ではない場合、初期化される前に他のメソッドでこの変数を使用すると、陥る可能性のある落とし穴になる可能性があります。その場合、ゼロで初期化された変数を格納する方がはるかに優れています。そのためassert、計算を行う前に有効な状態にすることができます。

于 2012-07-17T11:07:13.223 に答える
1

これらの変数がオブジェクトの状態の一部である場合は、それらをコピーする必要があります。変数がオブジェクトの状態の一部でない場合、それらはメンバーであってはなりません。インターフェイスの関数の結果が、操作を開始する前のその変数の値に依存する場合、変数はオブジェクトの状態の一部です。

mutable上記の一般的な規則にはいくつかの例外があります。特に、複雑な操作の結果の同期メカニズムまたはキャッシュとして、オブジェクトの状態に関与しないメンバー変数がいくつかあります(通常はとしてマークされます)。

問題に戻ると、説明から、これらのメンバーを異なるメンバー機能間の通信メカニズムとしてのみ使用しているように思われます。インターフェイスの1つの関数が値を設定してから、値を読み取り/変更する他の関数を呼び出します。その場合は、変数を引数として関数に渡すことを検討してください。メンバーを使用することで、これらの値に対する関数の依存関係を効果的に隠し、同時にクラスに依存関係を追加します。

インターフェイスの関数のいずれかがそれらのメンバーにアクセスする場合、これはさらに悪化します。この場合、割り当て(またはコピーの構築)後、ソースと宛先の動作が異なり、コピーの初期化/割り当て後にソースと宛先オブジェクトは同等です。

基本的に、実用的な観点から、それらのメンバーがオブジェクトの状態の一部でない場合、現在のアプローチから逃れることができるかもしれませんが、私は本当にデザインを再考します。それらがオブジェクトの状態に参加している場合は、決してそれらをコピーすることを避けてはなりません。

于 2012-07-17T12:43:40.887 に答える
1

c ++の観点からは、ここで問題はありませんが、c++は足を撃たれるのを防ぎません。数か月以内に、リリースビルドでのみ発生するエラーをデバッグしている可能性があります。その後、これが発生する理由を見つけるために数日を費やします。私のアプリがリリースで動作するのにデバッグでは動作しない理由はたくさんあります。原因の1つは、デバッグヒープが割り当てられたメモリを初期化することです。

于 2012-07-17T11:40:18.010 に答える