4

メンバ変数が他のクラスのオブジェクトへの boost::shared_ptrs である C++ クラス (dll プロジェクト内) があります。クラスコンストラクター内でそれらを割り当てる方が良いですか、それとも別の init() 関数を使用する方が良いですか?

boost::shared_ptr 内の T へのポインターのデフォルト値は NULL であると想定しています。したがって、コンストラクター内で何もしないと、Boost::shared_ptr の get() は Init() 関数を呼び出す前に NULL を返します。

また、割り当てステートメントの 1 つで new にメモリ割り当ての問題がある場合、(Init で) 例外をキャッチする必要がありますか、それともこの Init() の呼び出し元にその例外をキャッチするように指示するのがよいでしょうか? boost::shared_ptr a( new T);

単体テスト内でメモリ割り当ての例外をシミュレートする標準的なアプローチはありますか? すべてのオブジェクトが適切に割り当て解除されていることを確認します

4

3 に答える 3

2

メンバ変数が他のクラスのオブジェクトへの boost::shared_ptrs である C++ クラス (dll プロジェクト内) があります。クラスコンストラクター内でそれらを割り当てる方が良いですか、それとも別の init() 関数を使用する方が良いですか?

通常、コンストラクターですべてを行う方が適切です。
後で呼び出される init() 関数を持つことは、オブジェクトが構築後に有効ではないことを意味するため、init() が呼び出されたかどうかを示す状態フラグを保持し、パブリック メソッドが呼び出されて実行されるたびにそのフラグをチェックする必要があります。初期化されていないオブジェクトに適したもの

boost::shared_ptr 内の T へのポインターのデフォルト値は NULL であると想定しています。したがって、コンストラクター内で何もしないと、boost::shared_ptr の get() は Init() 関数を呼び出す前に NULL を返します。

はい: shared_ptr の既定のコンストラクターは、それを NULL に初期化します。

また、割り当てステートメントの 1 つで new にメモリ割り当ての問題がある場合、(Init で) 例外をキャッチする必要がありますか、それともこの Init() の呼び出し元にその例外をキャッチするように指示するのがよいでしょうか? boost::shared_ptr a( new T);

コンストラクターがある場合: 構築されたすべてのメンバーは (デストラクターを介して) 正しく破棄されますが、ユニット化されたオブジェクトは変更されず、現在のオブジェクトのメモリは割り当てられていないかのように解放されます (使用する別の正当な理由)イニシャライザリスト)。

init() を使用する場合: 次に、例外をキャッチしてオブジェクトを正しくクリーンアップし、メモリを解放する必要があります。オブジェクトの複雑さに応じて、init 内でこれを実行できる場合 (ただし、正しく実行するのは難しい)、または呼び出し元が実行する必要があります。その後、コンストラクターから例外がスローされた場合と同じことを行う必要があります (使用方法によって異なります)。

単体テスト内でメモリ割り当ての例外をシミュレートする標準的なアプローチはありますか? すべてのオブジェクトが適切に割り当て解除されていることを確認します

ファクトリ オブジェクトを使用してオブジェクトを割り当てることができます。
ファクトリ オブジェクトをコンストラクタに渡します。構築中に例外をシミュレートしたい場合は、その適切な例外を生成するモック ファクトリを渡すだけです。

于 2010-02-27T15:03:59.323 に答える
1

最初の質問では、理想的にはイニシャライザ リストを使用して、ポインタが有効であることを確認する必要があります。これを行わないと、ポインターを使用する前に、ポインターが有効かどうかを常に確認する必要がある可能性があります。特に、呼び出し元のコードに任せて呼び出す場合init()

一方、純粋な仮想を呼び出すことによってのみ設定できる場合は、これを行うことができない可能性があります。この場合、init()メソッドを使用する必要があります。

初期化では、キャッチして再スローするか、単にキャッチしないことができると思います。いずれにせよ、呼び出し元がメモリ割り当て例外をキャッチすることが望ましいと思います。

init()オブジェクトの呼び出しでメモリ割り当ての例外をテストしたい理由がわかりました。ここでのアプローチは、呼び出しで常にスローするスタブ オブジェクトを置き換えることです。init()

共有ポインターの割り当て解除を確認する理由がわかりません (生のポインターかもしれません) 確かに、共有ポインターのポイントは、共有ポインターを参照できる一方で、定義上、それを共有しているということです。まだ破壊されません。

おそらく、参照カウントをチェックしたり、指定したオブジェクトを設定したり、(破棄時に) テストで監視できるセマフォをクリアしたりできます。どういうわけかポイントを逃していますか?

于 2010-02-27T14:53:07.743 に答える
1

メンバーの割り当てには初期化子リストを使用します。これらが推奨されます (場合によっては唯一の方法です)。

オブジェクトの作成中に問題が発生した場合は、例外をスローして救済します。validまたは、使用中のオブジェクトが有効であることを確認するためだけに、メンバー関数が呼び出されるたびにチェックする必要があるフラグを維持する必要があります。

いつでも例外をキャッチして報告できます。解放が失敗した場合、理想的には、例外をスローするのではなく、dtor で処理し、報告して先に進むべきです。

于 2010-02-27T14:19:42.800 に答える