一个班轮的破坏者?

时间:2014-11-12 21:19:43

标签: c++ nodes destructor

如何为Node类编写单行析构函数?我假设有类似的东西,

~Node() {delete Node; };

将作为我的节点类的公共函数,但事实并非如此。作为参考框架,我的对象结构如下:

    template <class T>
    struct List{
        public:
              class Node{
                   public:
                        T* data;
                        Node* next;
                        //node attributes, and a destructor as below
                        ~Node() {delete Node; };
              }
        private:
              //private elements
        }
     }

3 个答案:

答案 0 :(得分:1)

首先,您需要确定是否确实需要析构函数:只有当编译器提供的默认析构函数不符合您的需求时才需要。通常,当类的对象持有“它们”拥有的其他对象的“普通”指针时,你最终会编写一个析构函数,而这在你帖子的代码中并非如此。

一旦您确定需要析构函数,就需要了解清理所需的内容。在链接列表情况下,您可能需要清理当前节点后面的节点链。您可以在一行代码中执行此操作,如下所示:

~Node() { delete next; } // No semicolon is necessary here

然而,这不是一个好的选择,因为删除Node *next将触发递归的删除链,这可能会溢出堆栈。您最好使用while循环跟随节点链,随时删除节点。在删除节点之前,您必须小心将next设置为nullptr,以避免双重删除:

~Node() {
    Node *curr = next;
    while (curr) {
        Node *tmp = curr;
        curr = curr->next;
        tmp->next = nullptr;
        delete tmp;
    }
    next = nullptr;
}

请注意,使用智能指针也可以。但是,在这种情况下,当列表太长时,您将面临堆栈溢出的风险,因为删除将以递归方式发生。

答案 1 :(得分:1)

*具有内容的析构函数通常仅在类分配内存时或者您希望在销毁时采取某些明确操作时才需要。而删除应指明要销毁的对象的实例。

例如,如果您有一系列链接的节点,并且想要在一个节点上调用delete时删除所有后续节点,则代码可能如下所示:

class Node {
 Node();
 ~Node();
 void link(Node * n);
private:
  Node * next;
}
Node::Node() {
 next = 0;
}
Node::~Node() {
 delete next;
}
Node::link(Node *n) {
 next = n;
}

答案 2 :(得分:0)

首先,提出一些建议:

尽可能使用智能指针,避免许多麻烦 std::unique_ptr没有任何开销。

接下来,考虑使Node成为一个简单的数据结构,没有任何花饰 List是进行繁重任务的更好地方。

这也允许你避免删除时的递归,而是使用更加理智的迭代。

template <class T> struct List{
    struct Node{
        std::unique_ptr<T> data;
        Node* next;
    }
    ~List() {
        Node* p = head;
        while(p) {
            Node* tmp = p->next;
            delete p;
            p = tmp;
        }
    }
    private:
          //private elements
    }
 }

另外,考虑一下你是否真的想要指向有效载荷,而不是Node中的有效载荷本身。