質問
インターフェイスオブジェクトへの(非スマート)ポインター(pInterfaceと呼びます)を持つクラスがあり、そのインターフェイスへのアクセスも必要とするネストされたクラスを構築しています。これを回避するには、次のように、インターフェイスへのポインターをネストされたクラスのコンストラクターに渡します。
CNestedClass someClass( pInterface, ... );
ただし、ネストされたクラスにこのポインターを保存する最善の方法はわかりません。使用できます:
1) A scoped (or other smart) pointer (to the original object)
2) A pointer to a pointer
何を提案しますか、なぜですか?
編集:私は明確にする必要があります-ネストされたクラスはインターフェイスオブジェクトのメソッドを呼び出す必要がありますが、それを作成しません(または「ポイントされた」オブジェクトを変更します)、親クラスがそれを担当します。
解決
ポインターへのポインターの使用は、いずれかのクラスがポインターの値を変更できる場合です。既存のオブジェクトを削除し、新しいオブジェクトと置き換えることにより。これにより、ポインターからポインターへの逆参照により、両方のクラスで同じオブジェクトを使用できます。
そうでない場合は、両方のクラスの存続期間中、オブジェクトが有効であることを確認する必要があります。
- ネストされたクラスの寿命が短い場合、実際に心配する必要はありません。
- 同じ順序であれば、正しい順序(たとえば、ネストされたクラスを最初に、オブジェクトを後で)でクリーンアップすれば、再度心配する必要はありません
- 所有者が破棄された後、ネストされたクラスが持続する可能性がある場合、オブジェクトも持続することを保証する方法を実装する必要があります。
オブジェクトの有効期間を確認する必要がある場合は、手動またはスマートポインターインターフェイスを使用して、参照カウントセマンティクスを使用して実行できます。
スマートポインターの場合、boost :: shared_ptrが適切な選択です。 shared_ptrを使用すると、オブジェクトの所有権を複数のポインターで共有できます。最後のshared_ptrが範囲外になると、オブジェクトは削除されます。
(これは、オブジェクトが排他的に所有されるauto_ptrの場合ではないことに注意してください。)
知っておくべきこと;
- boost :: shared_ptrを使用する場合は、ネストされたクラスに、参照/ポインターではなくshared_ptrのコピーがあることを確認してください。
- std :: auto_ptrの動作はまったく異なり、オブジェクトは排他的に所有され、共有されません
- boost :: shared_ptrはヒープオブジェクトでのみ機能します。たとえば、「new」の呼び出しから返されるポインター
例:
typedef boost::shared_ptr<Interface> shared_interface;
class NestedClass
{
shared_interface mInterface; // empty pointer
}
void NestedClass::setInterface(shared_interface& foo)
{
mInterface= foo; // take a copy of foo.
}
void ParentClass::init( void )
{
// mInterface is also declared as shared_interface
mInterface = new Interface();
mNestedClass->setInterface(mInterface);
}
他のヒント
ポインターへのポインターを使用するもう1つの理由は、 outer コードが元のポインター値を変更する可能性がある場合です(たとえば、新しいオブジェクトを指すようにする、またはNULLに設定する)オブジェクトを解放した後、それが指す)。ただし、IMOは他の人にポインタを渡した後にポインタを変更するのは非常に悪い習慣です。
したがって、外部コードもネストされたクラスもポインターを変更しない場合、元のポインターのコピーとしてメンバークラス(フィールド)としてネストされたクラスに保存するだけです。
インターフェイスへのポインタ(IMyInterface ** ppInterface)のアドレスを渡し、クラスによって実装されている場合はポインタを埋めます。
クラスは、thisポインターをそのインターフェイスにキャストし、ポインター* ppInterfaceに入力できます。 クラスがこのインターフェイスを実装しない場合、* ppInterfaceをNULLに設定できます。
基本的に、2つの異なるオブジェクト間で同じオブジェクトへのポインターを共有しています。スマートポインターを使用していない場合は、共有オブジェクトへのポインターを保存するだけです。共有オブジェクトの所有権、つまり、どのオブジェクトが共有オブジェクトの割り当てを解除し、他のユーザーにそのオブジェクトがなくなったことを通知する責任があることに注意する必要があります。
class Outer
{
class Inner
{
};
};
OuterのオブジェクトはpInterfaceオブジェクトへのRAWポインターのみを保持しているため、OuterオブジェクトはpInterfaceオブジェクトのライフスパンを所有していないか、制御できません。したがって、pInterfaceオブジェクトが外部オブジェクトと同じ長さで存続するという保証があることを願っています。この場合、参照を使用するだけでポインタを使用する理由はありません(pInterfaceがNULLになる状況がないと仮定します)。
Innerが「参照」(C ++参照ではない)をどのように保持するかは異なり、実際には、関係するオブジェクト間の関係に関する詳細情報が必要です。
- 内部オブジェクトと外部オブジェクトの間の実現性とは何ですか。
- pInterfaceポインターを継承したOuterオブジェクトに対するInnerオブジェクトの寿命はどのくらいですか?
- Outerオブジェクトの寿命がpInterfaceオブジェクトよりも短いという保証は何ですか。
etc。