2017-06-11 8 views
1

彼の "Effective STL" Meyersには、ポインタのベクトルを正しく消去する方法が示されています(std::vector::clearはポインタだけを削除し、占有するメモリは削除しません)。std :: unary_functionでポインタのベクトルをクリアする

そこで彼は、オブジェクトのデストラクタを呼び出しunary_functionとclear使用for_eachへの呼び出しの前にアドバイス:?なぜました:書籍DeleteMyObject2

template<typename T> struct DeleteMyObject2: public std::unary_function<const T*, void> 
{ 
    void operator()(const T* ptr); 
}; 

template<> struct DeleteMyObject2<algotest::ImageSelection> 
{ 
    void operator()(const algotest::ImageSelection* ptr) 
    { 
     delete ptr; 
     ptr=0; // this was added by me 
    } 
}; 

void std_clearing_pointers() 
{ 
    std::vector<ImageSelection*> vec; 
    vec.reserve(5); 
    for(int i=0; i<5; ++i) 
     vec.insert(vec.begin(), new ImageSelection()); 

    std::for_each(vec.begin(), vec.end(), DeleteMyObject2<ImageSelection>()); 

    // HERE elements of vec are not NULL !!! 
    vec.clear(); 
} 

は括弧なしで呼ばれていた、それは(question1をコンパイルしていません標準的な変更は):?

std::for_each(vec.begin(), vec.end(), DeleteMyObject2<ImageSelection>); 

とにかく、それはDeleteMyObject2のためであれば、コールoperator()をコンパイルしますが、前vec.clear()ベクトルのオブジェクトはNULLではありません。私は、STLコンテナが常にその要素をコピーするので、​​ポインタが値渡されるので、すべてが問題ないと思います(question2:私は正しいですか?)

私はrefでポインタを渡そうとしましたが、オブジェクトはfor_eachの後にNULLになりました。私はより安全だと感じました。

template<> struct DeleteMyObject1<algotest::ImageSelection> 
{ 
    void operator()(algotest::ImageSelection*& ptr) 
    { 
     delete ptr; 
     ptr=0; 
    } 
}; 

question3:それは不必要な割り当てをしていないためDeleteMyObject1よりDeleteMyObject2より好ましいですか?

ありがとうございます。

答えて

1

効果的なSTLが出てきたので、これを行うための、より短くてより読みやすい方法があります。 [](int *p){delete p;}delete任意のpに言っlambda or, anonymous, functionある場合たとえば、あなたが今、あなたの質問内のクラスのいずれよりもはるかに短いコードで、

vector<int *> a{new int{1}, new int{2}}; 
for_each(begin(a), end(a), [](int *p){delete p;}); 

を書くことができます。

スマートポインタのvector(たとえば、整数へのポインタのベクトルの場合はvector<shared_ptr<int>>)を考慮する必要があります。リソースの割り当てを解除する明示的なコードはエラーが発生しやすいです。ご質問については

  1. クラスあなたは、このクラスの(デフォルトで構築)オブジェクトをしたい示していると括弧で表示されます。この関数は、クラスではなくオブジェクトを要求します。

  2. ポインタを値(この場合は)で渡すと問題ありません。

関連する問題