2011-07-10 27 views
-2

数時間前に私はthis questionと尋ねました。 std :: vectorはデストラクタが呼び出されたときに要素のそれぞれを削除することを学びました。このプログラム(前の例の派生物)を考えてみましょう。std :: vector破壊と予期しないメモリリークpt 2

#include <vector> 
#include <iostream> 

class Bar { 
    int x; 
public: 
    ~Bar() { 
     std::cout << "~bar()" << std::endl; 
    } 
}; 

class Foo { 
    std::vector<Bar*> v; 
public: 
    Foo() { 
     this->v.push_back(new Bar()); 
     this->v.push_back(new Bar()); 
     this->v.push_back(new Bar()); 
    } 

    ~Foo() { 
    } 
}; 

int main() { 
    Foo f; 

    Bar* b = new Bar(); 

    // Bar::~Bar() called once 
    delete b; 

    // Bar::~Bar() not called three times as expected 

    return 0; 
} 

bのデストラクタが期待通りに呼び出されました。しかし、f.vのBar *要素のデストラクタは呼び出されません。 thisによると、f.vの各要素のデストラクタを呼び出す必要があります。私はここで何が欠けていますか?

+0

この新しい例は、前の例とまったく同じではありません。つまり、ポインタのコンテナがあります。 –

+0

ヘイ・ジェームズ:ここで重複して申し訳ありません。以前の質問に、私が意図していたより少し違ったことを尋ねたことがありました。 – rustushki

答えて

2

この質問に対する回答は、最後の質問に対する回答とまったく同じです。割り当てを解除するとdeleteが呼び出されないため、ポインタが指しているものは自動的に破棄されません。

他の言い方をすれば、Barにはデストラクタがありますが、Bar*はありません。したがって、std::vector<Bar>は、は各要素のデストラクタを呼び出します。

0

あなたはFooを破壊していないので、このケースでもbを削除しています(そして、デストラクタはとにかく何もしません)、削除されません。プログラムが終了すると、すべてのものが取り除かれます(デストラクタを呼び出す必要はありません)。

3

my previous answerで説明したように、ポインタ(Bar *)を破棄してもオブジェクト(Bar)は破棄されません。ベクターはポインタBar *を3回破壊しますが、これはノーオペレーションであり、指されているBarは残されているため、何も表示されません。 std::vector<Bar>を使用した場合はBarが破棄され、3回生と呼ばれるデストラクタが表示されます。

+0

もう一度bdonlanに感謝します。私は今、それを得ると思います:Bar *へのポインタは削除されます。これはmain()のdelete bとは異なる*です。その場合、オブジェクト自体は実際に削除されます。この例では、デストラクタが呼び出されていないときに、各要素のデストラクタを呼び出さなければならないと文書に記載されている理由は、私を混乱させる原因です。 – rustushki

+0

要素は 'Bar *'であり、 'Bar'ではありません。 'Bar *'のデストラクタが呼び出されます。 'Bar'のデストラクタはそうではありません。 – bdonlan

+1

ああ!はい!それは違いです! Bar *のデストラクタはBar ::〜Bar()ではありません。これを私に説明してくれてありがとう:-) – rustushki

関連する問題