如果容器中包含了通過new操作創建的指針,切記在容器對象析構前將指針delete掉

當容器中包含的是通過new的方式分配的指針時,指針容器在自己被析構時會析構所包含的所有元素,但指針的“析構函數”不做任何事情!它當然也不會調用delete

1.可用於for_each的僞函數

template<typename T>
struct DeleteObject :                           // 條款40描述了爲什麼
        public unary_function<const T*, void> { // 這裏有這個繼承
        void operator()(const T* ptr) const
        {
                delete ptr;
        }
};

 for_each(vwp.begin(), vwp.end(), DeleteObject<Widget>);

2.從沒有析構函數的類公有繼承是c++大忌 

3.你可以通過編譯器推斷傳給DeleteObject::operator()的指針的類型來消除這個錯誤(也減少DeleteObject的用戶
需要的擊鍵次數)。我們需要做的所有的事就是把模板化從DeleteObject移到它的operator():

struct DeleteObject {                           // 刪除這裏的
                                                // 模板化和基類
        template<typename T>                    // 模板化加在這裏
        void operator()(const T* ptr) const 
        { 
                delete ptr; 
        } 
}

編譯器知道傳給DeleteObject::operator()的指針的類型,所以我們可以讓它通過指針的類型自動實例化一個
operator()。這種類型演繹下降讓我們放棄使DeleteObject可適配的能力(參見條款40)。

for_each(dssp.begin(), dssp.end(),DeleteObject ());

4.對於第3中方式

直截了當而且類型安全,正如我們喜歡的一樣。
但仍不是異常安全的。如果在SpecialString被new但在調用for_each之前拋出一個異常,就會發生泄漏。
void doSomething()
{
        typedef boost::shared_ ptr<Widget> SPW; //SPW = "shared_ptr
                                                // to Widget"
        vector<SPW> vwp;
        for (int i = 0; i < SOME_MAGIC_NUMBER; ++i)
                vwp.push_back(SPW(new Widget)); // 從一個Widget建立SPW,
                                                // 然後進行一次push_back
                ...                     // 使用vwp
}                                       // 這裏沒有Widget泄漏,甚至
                                        // 在上面代碼中拋出異常


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章