析构函数永远不会调用

时间:2015-01-29 16:59:46

标签: c++ c++11

我不明白为什么 ListELement 的析构函数永远不会被调用  我使用 Base 类作为计数器, ListELement 派生自 Base 以使用计数器。

该计划:

#include <iostream>
#include <random>
#include <functional>

using namespace std;

class Base{
    protected:
    static int count;
};


template <class T>
class ListElement: public Base{

    public:
    ListElement(const T& value): next(NULL), data(value) { count++;}
    ~ListElement() { cout<<"dead:"<<count<<endl;}

    //Setter
    void SetData(const T& value) { data=value; }
    void SetNext(ListElement* elem) { next = elem; }
    //Getter
    const T& GetData() const { return data; }
    ListElement* GetNext() const { return next; } 

    private:
    T data; 
    ListElement* next;
};

int Base::count = 0;

int main(){
    random_device rd;
    default_random_engine generator(rd());
    uniform_int_distribution<int> distribution(1,100);
    auto dice = bind(distribution, generator);

    int nListSize = 1;
    ListElement<int>* nMyList = new ListElement<int>(999);

    ListElement<int>* temp = nMyList;//nMyList is the first element
    for(int i=0; i<10; ++i) {
        ListElement<int>* k = new ListElement<int>(dice()); //New element
        temp->SetNext(k);
        temp = temp->GetNext(); 
        nListSize++;    
    }

    temp=nMyList;
    for(int i=0; i<nListSize; ++i){
        cout<<"Value["<<i<<"]: "<<temp->GetData()<<endl;
        temp = temp->GetNext();
    }

    return 0;
}

这是我的输出:

Value[0]: 999
Value[1]: 61
Value[2]: 14
Value[3]: 96
Value[4]: 51
Value[5]: 15
Value[6]: 37
Value[7]: 83
Value[8]: 1
Value[9]: 42
Value[10]: 95

如果我输入echo &?,控制台会返回0,所以一切都会好的。

3 个答案:

答案 0 :(得分:4)

new少数ListElement<int>但从未delete他们。

自动调用具有自动存储持续时间的变量的析构函数。它们不适用于您手动分配内存的变量。

如果添加正确的删除语句,则会运行dtors。

注意:如果你绝对需要一个指针,你应该查看std::shared_ptr / std::unique_ptr,因为你将拥有一个指针的语义,为你完成内存管理,即指针将一旦没有被引用,就被正确删除。

答案 1 :(得分:0)

对于每个明确的new调用,除非 ListElement 析构函数具有删除这些节点的循环,否则您将需要显式delete调用。

答案 2 :(得分:0)

因为必须使用operator delete显式释放使用operator new创建的对象。

这可以通过使用设施来实现,或者将nMyList的类型更改为(在C ++ - 11之前)

std::auto_ptr<ListElement<int> > nMyList(new ListElement<int>(999));

或(来自C ++ 11,弃用auto_ptr)

std::unique_ptr<ListElement<int> > nMyList(new ListElement<int>(999));

如果你坚持不改变nMyList的类型,那么

delete nMyList;
main()末尾的

也可以工作(智能指针类型的优势在于它们会破坏他们管理的对象)。