返回*这引起了很大的挫败感

我已经使用 C 大约一年了,最后决定学习 C++。我正在尝试像这样实现我自己的链表类:

#include <cstdio>
#include <cstdlib>

struct linked_list_node
{
    int value;
    struct linked_list_node* next;
};

class LinkedList
{
    linked_list_node* head;
public:
    LinkedList add(int value)
    {
        printf("add calledn");
        if (head == nullptr)
        {
            head = new linked_list_node;
            head->value = value;
            head->next = nullptr;
        }
        else
        {
            linked_list_node* curr = head;
            while (curr->next != nullptr) curr = curr->next;
            curr->next = new linked_list_node;
            curr->next->value = value;
            curr->next->next = nullptr;
        }
        return *this;
    }
    int get(size_t index)
    {
        linked_list_node* curr = head;
        for (int i = 0; i < index; i++) curr = curr->next;
        return curr->value;
    }
    LinkedList()
    {
        head = nullptr;
    }
    ~LinkedList()
    {
        linked_list_node* curr = head, * temp;
        while (curr != nullptr)
        {
            temp = curr;
            curr = curr->next;
            delete temp;
        }
    }
};

int main()
{
    LinkedList l;
    l.add(1);
    l.add(2);
    printf("%dt%dn", l.get(0), l.get(1));
    return 0;
}

这会导致发生异常。我发现了错误,这是方法add返回*this. 这导致析构函数在 之后被调用l.add(1),从而删除了对 的分配head并搞砸了整个程序。将add方法定义为:

void add(int value) // void method
{
    printf("add calledn");
    if (head == nullptr)
    {
        head = new linked_list_node;
        head->value = value;
        head->next = nullptr;
    }
    else
    {
        linked_list_node* curr = head;
        while (curr->next != nullptr) curr = curr->next;
        curr->next = new linked_list_node;
        curr->next->value = value;
        curr->next->next = nullptr;
    }
    // doesn't return *this
}

代码运行完美。有人可以解释为什么返回*this会导致析构函数被调用。提前致谢 :)

回答

你的add函数返回一个副本LinkedList。由于您没有提供复制构造函数,因此您使用的是编译器生成的构造函数,它只是逐个元素地复制成员。当您复制指针时,进行双重释放或在指针被释放后尝试使用指针会带来巨大的危险。

有一条准则称为“三规则”(请参阅什么是三规则?),它说如果您有构造函数或析构函数,则可能也需要有复制构造函数。这是为了让你远离这种麻烦。


以上是返回*这引起了很大的挫败感的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>