C++中List类的析构函数

Mel*_*art -1 c++ containers memory-management object-lifetime singly-linked-list

我是C++的新手,因此这个问题.我在C++中有一个单一链接列表的玩具实现.

template<typename T>
class List {
    template<typename U>
    struct Node {
        U data_;
        Node<U>* next_;

        Node() : data_(0), next_(nullptr) {}
        Node(U data) : data_(data), next_(nullptr) {}
    };

private:
    Node<T>* head_;
    std::size_t size_;

public:
    List() : head_{nullptr}, size_{0} {}

    void insert(const T& item) {
        Node<T>* p(new Node<T>(item));
        if (size_ == 0) {
            head_ = p;
        } else {
            p->next_ = head_;
            head_ = p;
        }
        size_++;
    }
    std::size_t getSize() {
        return size_;
    }

    ~List(){
    while(head_){
        Node<T> p = head_;
        delete(p);
        head_ = head_->next_;
    }
};
Run Code Online (Sandbox Code Playgroud)

这段代码似乎有效.但问题是new,尽管有~List()析构函数,但从未清理过分配的对象.有人可以帮助我理解,我怎么能为这个类编写一个析构函数来清理所有分配的节点?

重要说明:我知道这可以使用智能指针来完成,但我想了解旧学校管理堆栈的方法.

Bar*_*ani 7

while(head_){
    Node<T> p = head_; <-- change to pointer
    delete(p); <-- you can't delete this right now
    head_ = head_->next_;
}
Run Code Online (Sandbox Code Playgroud)

p应该是一个指针.你不能p马上删除.您必须找到该next节点,然后再删除p.也可以使用delete p;而不是delete (p);如下:

~List() {
    while(head_) {
        Node<T> *p = head_;
        head_ = head_->next_;
        delete p;
    }
}
Run Code Online (Sandbox Code Playgroud)

如评论中所述,Node不需要是模板.你可以简化你的课程.insert也可以简化,因为head_初始化为nullptr,你可以安全地分配p->next_ = head_;

template<typename T> class List {
    struct Node {
        T data_;
        Node* next_;
        Node() : data_(0), next_(nullptr) {}
        Node(T data) : data_(data), next_(nullptr) {}
    };
    Node* head_;
    std::size_t size_;
public:
    List() : head_{ nullptr }, size_{ 0 } {}

    void insert(const T& item) {
        Node* p = new Node(item);
        p->next_ = head_;
        head_ = p;
        size_++;
    }

    std::size_t getSize() {
        return size_;
    }

    ~List() {
        while(head_) {
            Node *marked = head_;
            head_ = head_->next_;
            delete marked;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)