0
class LinkedList
{
public:
    LinkedList() : _head(nullptr) {}
    LinkedList(ListElement *newElement) : _head(newElement) {}
    ~LinkedList() {  };
    LinkedList(const LinkedList& LL);
    LinkedList& operator=(LinkedList byValLinkedList);
private:
    ListElement *_head;
}
LinkedList::LinkedList(const LinkedList & LL)
{
    ListElement *curr = LL._head;

    // If Linked List is empty
    if (isEmpty() && curr != nullptr) {
        _head = new ListElement(curr->getValue());
        curr = curr->getNext();
    }

    ListElement *newNode = nullptr;
    while (curr) {
        newNode = new ListElement(curr->getValue());
        curr = curr->getNext();
    }
}

LinkedList& LinkedList::operator=(LinkedList byValLinkedList)
{

std::swap(_head, byValLinkedList._head);
return *this;
}


int main() {
    using namespace std;
    LinkedList LL1(new ListElement(7));
    //..... some insertions
    LinkedList LL2(new ListElement(5));
    //..... some insertions
    LL1 = LL2;  // What is the order ?
    // ..... do something else
    return 0;
}

当 LL1 = LL2 被执行时,应该调用哪一个。

我希望复制分配会发生。但是代码是按以下顺序执行的

  1. 复制构造函数
  2. 复制分配
  3. 析构函数

我究竟做错了什么 ?为什么要调用析构函数?

4

3 回答 3

1

你没有做错任何事,这正是复制和交换应该如何工作的。

调用复制构造函数来设置按值传递的参数。这很好,因为否则您的复制分配运算符将必须包含用于制作副本的代码。这样,您可以重用复制构造函数中的逻辑。

然后,参数超出范围并在函数结束时被销毁。由于交换调用,参数现在包含以前由 持有的资源*this。也非常可取,因为析构函数负责释放它们 - 否则您将不得不为复制赋值运算符编写清理代码,以正确删除被赋值替换的数据。

除了代码重用之外,复制和交换还为您提供异常安全性。如果您直接将副本复制到左侧对象 ( *this) 中,那么如果出现任何问题,您已经丢失了旧值并且不能保持不变。但是使用复制和交换,复制构造函数首先完成它的工作——如果出现任何问题,例如内存不足,*this则保留其先前的值。

这里对复制和交换习语有非常广泛的解释:

于 2016-05-31T01:24:55.217 回答
1
 LinkedList& operator=(LinkedList byValLinkedList);

您的复制构造函数按值获取其参数。这意味着

 LL1=LL2;

需要复制LL2, 以便按值传递。这就是“按价值传递”的意思。因此,复制构造函数。

为避免进行复制构造,赋值运算符必须通过引用获取其参数,而不是:

 LinkedList& operator=(const LinkedList &byValLinkedList);

这意味着,当然,您不能完全使用std::swap. 但那将是一个不同的问题......

简而言之,您有两个选择:要么实现两个复制构造函数,一个接受const引用,一个不接受,后者能够使用std::swap. 或者,声明_headmutable.

于 2016-05-31T01:09:23.783 回答
0

在您的赋值运算符中, byVallinkedList 是按值传递的。该 LinkedList 对象是使用您的复制构造函数初始化的

于 2016-05-31T01:12:01.693 回答