1

私はクロスプラットフォームC++で作業しており、いくつかのクラスを次のように定義しています:(この例では大幅に簡略化されています)

class ExampleBase
{
public:
    ExampleBase( int blah ) : blah_test(blah) { }

    virtual void DoSomething( ) = 0;
private:
    int blah_test;
};

class ExampleImplementer : public ExampleBase
{
public:
    ExampleImplementer( ) : ExampleBase( 5 ) { }

    virtual void DoSomething( ) { /* unique implementation here */ }
};

元々、私は単一のクラスしか持っていませんでした。それは、std :: vectorにインスタンスの束を格納し、const参照によって渡されました。しかし今、私は基本クラス(純粋な仮想を維持したい)といくつかのポリモーフィック実装クラスを持っている必要があります。

実装インスタンスのコレクションを持ちながら、スタックにstd :: vectorを割り当てるなど、リークのない簡単なメモリ管理を行うための最良の方法は何ですか?

  • std :: vectorはクラスが非純粋な仮想である必要があるため(内部割り当て/コピーなどを行うため)、明らかにstd ::vector<ExampleBase>を使用することはできません。コードのユーザーが誤ってExampleBaseのインスタンスを作成してほしくないのは、それが間違っているからです。また、オブジェクトのスライスやその他の厄介な問題の可能性を回避したいと思います。

  • 一連のstd::auto_ptr作業で十分ですが、すべてを初期化して、「空きスロット」を探し、イテレータなどを探す必要があります。このホイールの再発明をすべて行うのは少しおかしいようです。

  • boost::ptr_vector有望に見えましたが、Linuxでビルドする場合、ExampleBaseが非純粋な仮想である必要があるという点で、少し奇妙な動作をします。理由はわかりませんboost::ptr_vector

これは単純なようで、おそらく本当に一般的な状況です。では、これを行うための最良の方法は何ですか?私はこれを行う他の標準またはブーストの方法を受け入れています:「最良」の方。

4

4 に答える 4

6

boost::ptr_vectorあなたがブーストを持つことができるなら行く方法です。シナリオで機能するはずです。機能しない場合は、他の問題が発生しているため、エラーメッセージを投稿してください。

または、に行くこともできますstd::vector< boost::shared_ptr<ExampleBase> >。これはあまり理想的ではありません。これは、特にベクトルのサイズが変更された場合に、再カウントによってオーバーヘッドが追加されるためですが、それ以外の場合は機能するソリューションです。

実装がTR1(g ++およびMSVCの最新バージョン)をサポートしている場合は、std::tr1::shared_ptr代わりに使用できます。STLの実装は、内部の知識に基づいて自由に最適化できるため、これは実際には優れている可能性があります。たとえば、MSVCでは、のコピーコンストラクターの代わりにstd::vector使用できることを認識しており、これを実行して、定期的なrefcountの変更を回避します。swapstd::tr1::shared_ptr

于 2009-09-26T06:01:21.960 に答える
3

いくつかのオプションがあります。

  • コンテナとしてboost::ptr_vectorを使用します。抽象ベースクラスでも機能するはずです。基本クラスに仮想デストラクタが含まれていることを確認してください。
  • 派生クラスのさまざまなオブジェクトを直接管理する複数のコンテナーを使用し、ポインターのみを使用する別のコンテナーを作成します。これは面倒な場合があり、ポインタが無効になるタイミング/場合について考える必要があります。ただし、同じタイプのオブジェクトを互いに近づけるという利点もあります。
  • スマートポインター(boostの共有所有権ポインターなど)を使用して、コンテナーに格納します。C ++ 0xは、所有権を共有したくない場合に適用できる、オーバーヘッドの少ない別の優れたスマートポインター、unique_ptrを提供します。残念ながら、C++03ではこれを適切にエミュレーションすることはできません。
  • 他の形式の「ハンドル」を使用します。これは、値セマンティクスを持つポインターを介してポリモーフィックオブジェクトをラップおよび管理するオブジェクトです(これは、「clone_ptr」という名前の別のスマートポインターになります)。
于 2009-09-26T06:00:43.163 に答える
1

boost::shared_ptr

于 2009-09-26T05:59:46.893 に答える
1

Boostを使用できる場合は、ポインターコンテナーを試してください

http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html

于 2009-09-26T06:00:21.727 に答える