Boost の Pool インターフェイスなど、shared_ptr によって管理されるオブジェクトをプールから割り当てたいのですが、どうすれば実現できますか?
3 に答える
あなたが望むことをするためのコードは次のとおりです(手元にブーストがなく、メモリから書いているため、おそらくコンパイルされません):
class YourClass; // your data type, defined somewhere else
boost::object_pool<YourClass> allocator;
void destroy(YourClass* pointer)
{
allocator.destroy(pointer);
}
boost::shared_ptr<YourClass> create()
{
// usage of object_pool<??>::construct requires that you have a
// YourClass::YourClass(void) defined. If you need to pass arguments
// to the new instance, you need to do that separately.
//
// for example using a YourClass::Initialize(your,parameters,here) method
// before returning from this function
return boost::shared_ptr<YourClass>( allocator.construct(), &destroy );
}
// usage:
boost::shared_ptr<YourClass> newObject = create();
これを 2 つの異なるプロジェクトで 2 回実装しました。どちらの場合も、作成関数と破棄関数は同期され (boost::mutex
アロケーターの使用にロックを追加できます)、それらはファクトリ クラスのメンバーでした (およびdestroy
の署名はvoid (YourClass*)
の使用によってに変更されましたboost::bind
)。
また、boost::shared_ptr コンストラクターで直接バインドすることにより、2 つの余分な関数 (destroy
およびcreate
)を記述することを回避できます。object_pool<YourClass>::destroy
私は今それをすべて書くのが面倒です:)。
編集(コードの書式設定のために、回答のコメントをここに移動しました):
destroy 関数をバインドするには:
class ClassFactory
{
boost::object_pool<YourClass> allocator;
public:
boost::shared_ptr<YourClass> create()
{
return boost::shared_ptr<YourClass>(
allocator.construct(),
boost::bind(&ClassFactory::destroy, this, _1) );
}
void destroy(YourClass* pointer)
{
allocator.destroy(pointer);
}
};
ClassFactory
よりも長い有効期間を持つ必要がありますshared_ptr
(ClassFactory
インスタンスが削除された場合、インスタンスに渡された this ポインターは無効になり、インスタンスが削除さshared_ptr
れるとアプリがクラッシュします)。shared_ptr
YourClass
明らかな解決策:
独自のmake_shared
関数を作成し、このメソッドの使用を created に強制しますshared_ptr
。ルールに由来する者は罰せられる。
ノート:
の役割に混乱があるようshared_ptr
です。その役割は、あなたが割り当てたメモリを管理することですが、そのためには独自の割り当て (カウンターとデリータ) が必要なため、それらのアロケータを渡すことができます。
これらはほぼ直交する懸念事項です。オブジェクトの割り当てshared_ptr
には関与しません。
関係するのは、参照されなくなったメモリの削除です。デフォルトのヒープ以外から割り当てた場合は、カスタムのデリータを提供する必要があります