5

私は現在、opengl を使用した低レベルのコーディングのために C++ に取り掛かっています。私は objc の経験が豊富なため、メモリ管理についてはある程度理解していますが、「ブースト」ライブラリがptr_vector.

私の問題は、ptr_vectorがそれ自体とそのオブジェクトの破壊をどのように管理するかがわからないという事実に関連していると思います。

次のコードを見てください。

// Header file
...
ptr_vector<IObject3D> objects;
...

// Implementation file
...
void ApplicationEngine::init()
{
    WavefrontObject3D *object = new WavefrontObject3D("Ninja.obj");
    objects.push_back(object); 
}
...

それで、実際の質問について:「オブジェクト」変数を介してここでリークを作成していますか?

私は objc で明示的な呼び出しを使用してオブジェクトを手動で保持および解放することに慣れています。以前alloc initは WavefrontObject3Dobjectを使用し、それを配列に追加し、その後release同じオブジェクトをリークを回避する必要がありました。

しかしdelete object、呼び出しの後に追加するpush_backと、WavefrontObject3D のデコンストラクターobjectが呼び出されます。これにより、変数ptr_vectorが保持されていないことがわかります。object私の仮定は正しいですか?

追加の、しかし関連する質問:含まれているクラスを破棄したいとしましょう。それが管理する、または要素でApplicationEngine何らかのデコンストラクターを呼び出す必要はありませんか?ptr_vector

4

4 に答える 4

6

いいえ、これはリークを作成しません。すべてptr_*のコンテナは、コンテナがスコープ外になると、格納されているオブジェクトを削除します。

コンテナにオブジェクトを追加した後にオブジェクトを削除すると、コンテナがオブジェクトをundefined behavior再度削除しようとするので作成します。

追加の質問: いいえ、ptr_vectorby 値を保存すると、その有効期間は周囲のクラスのスコープによって管理されます。

の簡単な実装を書きましょうptr_vector。間接的なイテレータやカスタムのデリータ、その他多くのものはサポートされていませんが、使用される原則が示されています。

template <typename T>
class ptr_vector {
public:
  // assume control over it
  void push_back(T* x) 
  { if(x) c_.push_back(x); else throw bad_pointer(); }

  ~ptr_vector() { 
    // delete everything that is stored here
    for(auto x : c_)  delete x;
  }
private:
  std::vector<T*> c_;
};


// a user class
struct user_class {
  void addSomething() { x.push_back(new int(23)); }
  ptr_vector<int> x;
};

ユーザー クラスがスコープ外になると、のデストラクタptr_vectorが呼び出され、すべてのメモリが再利用されます。目に見える漏れはありません。

于 2012-07-26T09:20:48.160 に答える
2
void push_back( T* x );

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

template
    < 
        class T, 
        class CloneAllocator = heap_clone_allocator,
        class Allocator      = std::allocator<void*>
    >
    class ptr_vector : public ptr_sequence_adapter
                              <
                                  T,
                                  std::vector<void*,Allocator>,
                                  CloneAllocator
                              >

CloneAllocatorしたがって、ptr_vectorに格納されている要素を削除せずに独自に指定できますが、 heap_clone_allocator(のデフォルトのパーCloneAllocator)はデストラクタに格納されているすべての要素を削除します。

http://www.boost.org/doc/libs/1_50_0/libs/ptr_container/doc/reference.html#class-heap-clone-allocator

于 2012-07-26T09:19:37.383 に答える
0

ptr_containersは、渡したポインタが指すメモリを所有します。クローン可能な概念の詳細については、ドキュメントを お読みください。

于 2012-07-26T09:24:08.867 に答える
0

ptr_vectorデストラクタ内のすべての要素を解放するので、すでに行っていること以外に何もする必要はありません。つまり、オブジェクトを作成し、それらをに追加してptr_vector、管理を任せます。明示的に呼び出すdeleteと、オブジェクトは2回破棄されます(1回は要求したとき、もう1回はptr_vector終了したとき)。つまり、ptr_vectorオブジェクトを複製しません。

終了時にApplicationEngine、のインスタンスがある場合は、ptr_vectorそのベクトルのデストラクタが呼び出され、追加されたオブジェクトが削除されます。

于 2012-07-26T09:18:42.687 に答える