1

Boost Pointer Containerの最初の例では、生のポインターを構造体に追加します。

class zoo
{
    boost::ptr_vector<animal> the_animals;
public:

    void add_animal( animal* a )
    {
        the_animals.push_back( a );
    }
};

しかし、push_back再割り当てをトリガーする可能性のある 、またはその他のメンバー関数がプロセス中に例外をスローした場合はどうなるでしょうか? 私の理解では、その場合、特定のオブジェクトのメモリを管理するのは呼び出し元次第ですが、呼び出し元はメモリを管理することを目的とするクラスに生のポインターを渡すため、呼び出し元がそうしない可能性が最も高いです。 t。

では、上記のコード例である種の固有のスマート ポインターを使用してポインターをコンテナーに提供する前にラップし、メモリー リークが発生しないことを確実にする必要はないでしょうか? コンテナーは、このようなスマート ポインターのオーバーロードを提供しますが、それらの使用を強制しません。

それとも、追加操作中にコンテナーが例外をスローすることはなく、常に成功するという議論ですか?

4

1 に答える 1

1

std::vector<animal*>の代わりにを使用していた場合、懸念事項は非常に有効ですboost::ptr_vector<animal>。Boost.PointerContainer は、解放する必要があるリソースへのポインターを処理するように設計されているため、そのようなことを心配する必要はありません。

Boost のドキュメントでは、さまざまなメンバー関数の例外安全性の保証が提供されています。ptr_vectorから継承push_backし、 asptr_sequence_adaptorの動作をリストしますpush_back

void push_back( T* x );

要件:x != 0
効果: ポインターをコンテナーに挿入し、その所有権を取得する
スロー: bad_pointerifx == 0
例外の安全性: 強力な保証

強力な保証とは、スローされた場合push_back、コンテナーの状態が呼び出しの直前の状態にロールバックされ、push_backリソースがリークされないことを意味します。さて、それはコンテナに追加しようとしていたリソースについて何も保証しないと主張することができますが、特に呼び出しpush_backが呼び出し元から渡されたオブジェクトの所有権を取得することになっています。

の実装を見ると、追加しようとしているリソースがリークされていないことがpush_backどのように保証されているかがわかります。ptr_vector

void push_back(value_type x)  // strong               
{
    this->enforce_null_policy(x, "Null pointer in 'push_back()'");

    auto_type ptr(x);           // notrow
    this->base().push_back(x);  // strong, commit
    ptr.release();                // nothrow
}

auto_typeそのため、実際のpush_back操作が試行される前に、まずanが構築されます。もう少し掘り下げるauto_typeと、 が のエイリアスであることがわかりstatic_move_ptrます。これは、必要に応じて、破棄時に所有するリソースを解放するスマート ポインター型です。

したがって、示されている例ではanimal *、例外がスローされた場合でも、追加しようとしている がリークされることはありません。

于 2015-05-21T17:08:31.647 に答える