这是我的节点结构的正确析构函数吗? 我有这个C++结构: struct Node { char symbol; unsigned int index; vector<Node*> next; // Constructors Node():symbol('$'), index(0), next(0) {} Node(char &c, const unsigned int &ind):symbol(c), index(ind), next(0) {} // Add a new character Node* add(char &c, const unsigned int &num) { Node *newChar = new Node(c, num); next.push_back(newChar); return newChar; } // Destructor ~Node() { for (int i = 0; i < next.size(); i++) delete next[i]; } };

这是我的节点结构的正确析构函数吗? 我有这个C++结构: struct Node { char symbol; unsigned int index; vector<Node*> next; // Constructors Node():symbol('$'), index(0), next(0) {} Node(char &c, const unsigned int &ind):symbol(c), index(ind), next(0) {} // Add a new character Node* add(char &c, const unsigned int &num) { Node *newChar = new Node(c, num); next.push_back(newChar); return newChar; } // Destructor ~Node() { for (int i = 0; i < next.size(); i++) delete next[i]; } };,c++,destructor,C++,Destructor,虽然只要删除main中的根节点,代码就不会泄漏内存,但这并不是真正的最佳选择 您应该避免使用new和delete,而是更喜欢智能指针。在这种情况下,请使用unique_ptr 另外,不要在堆上创建根节点,只需按如下方式创建它: Node root; // use root normally 您也没有正确地遵循5的规则,如果您使用unique_ptr,您甚至不需要担心它,因为您没有自定义dtor。也没有理由使用c和ind by ref和const ref,只需按值传递它们,因为您甚至不需要更改它

虽然只要删除main中的根节点,代码就不会泄漏内存,但这并不是真正的最佳选择

您应该避免使用new和delete,而是更喜欢智能指针。在这种情况下,请使用unique_ptr

另外,不要在堆上创建根节点,只需按如下方式创建它:

Node root;
// use root normally
您也没有正确地遵循5的规则,如果您使用unique_ptr,您甚至不需要担心它,因为您没有自定义dtor。也没有理由使用c和ind by ref和const ref,只需按值传递它们,因为您甚至不需要更改它们,而且按值传递与按ref传递原语一样便宜

通过这些更改,代码如下所示

struct Node {
    char symbol;
    unsigned int index;
    vector<std::unique_ptr<Node>> next;

    // Constructors
    Node():symbol('$'), index(0){}
    Node(char c, unsigned int ind):symbol(c), index(ind) {}

    // Add a new character
    Node* add(char c, unsigned int num) {
        next.push_back(std::make_unique<Node>(c, num));
        return next.back().get();
    }
};

虽然只要删除main中的根节点,代码就不会泄漏内存,但这并不是真正的最佳选择

您应该避免使用new和delete,而是更喜欢智能指针。在这种情况下,请使用unique_ptr

另外,不要在堆上创建根节点,只需按如下方式创建它:

Node root;
// use root normally
您也没有正确地遵循5的规则,如果您使用unique_ptr,您甚至不需要担心它,因为您没有自定义dtor。也没有理由使用c和ind by ref和const ref,只需按值传递它们,因为您甚至不需要更改它们,而且按值传递与按ref传递原语一样便宜

通过这些更改,代码如下所示

struct Node {
    char symbol;
    unsigned int index;
    vector<std::unique_ptr<Node>> next;

    // Constructors
    Node():symbol('$'), index(0){}
    Node(char c, unsigned int ind):symbol(c), index(ind) {}

    // Add a new character
    Node* add(char c, unsigned int num) {
        next.push_back(std::make_unique<Node>(c, num));
        return next.back().get();
    }
};

这是链表的一部分吗?如果是,那么如果您想删除单个节点而不是分解整个链表,该怎么办?如果节点拥有所有下一个指针,并且所有下一个指针都拥有,依此类推,如果其他任何节点都没有使用任何指针指向的任何对象,那么当然,这是正确的。因为您只能使用add创建非循环树,析构函数释放了一个节点的整个分支,这个构造应该可以完美地工作。它不是一个链表,它是一个trie结构,我把它看作一棵树。这是链表的一部分吗?如果是,那么如果您想删除单个节点而不是分解整个链表,该怎么办?如果节点拥有所有下一个指针,并且所有下一个指针都拥有,依此类推,如果其他任何节点都没有使用任何指针指向的任何对象,那么当然,这是正确的。因为您只能使用add创建非循环树,析构函数释放了一个节点的整个分支,这种构造应该可以完美地工作。它不完全是一个链表,它是一个trie结构,我把它看作一棵树。感谢您重新编写代码,非常感谢。我曾多次尝试学习智能指针,但从未找到好的教程。我可能会用这个例子开始。有一个案例是添加返回的节点&而不是节点*。如果没有编译器的抱怨,使用引用进行oops要困难得多,如果您真的需要地址,它只需要一个&away。@user4581301我同意,但我试图保留返回类型,以便OP理解如何从使用原始指针转换为智能指针。感谢您重新编写代码,非常感谢。我曾多次尝试学习智能指针,但从未找到好的教程。我可能会用这个例子开始。有一个案例是添加返回的节点&而不是节点*。在没有编译器抱怨的情况下,使用引用进行oops要困难得多,如果您确实需要地址,它只需要一个&away。@user4581301我同意,但我试图保留返回类型,以便OP理解如何从使用原始指针转换为智能指针。