对链表复制构造函数和赋值运算符使用 copy() 方法

Using a copy() method for a linked list copy constructor and assignment operator

我正在尝试为链表实现复制构造函数。我写了一个复制方法,它 returns 一个将用于复制构造函数并重载赋值运算符的列表:

template<class T>
SinglyList<T> SinglyList<T>::copy(Node *u) {
        SinglyList<T> newList;
        Node *current = u;
        if (current->next==NULL) {
          newList.add(current->x);
        } else while (current!=NULL) {
            newList.add(current->x);
            current = current->next;
            }
        return newList;
}

使用上面使用的 add() 方法:

template<class T>
void SinglyList<T>::add(T x) {
    Node *u = new Node(x);
    if (n == 0) {
        head = u;
    } else {
        tail->next = u;
    }
    tail = u;
    n++;
}

我一直在尝试这样实现复制构造函数:

template<class T>
SinglyList<T>::SinglyList(const SinglyList<T> &a) {
    this->copy(a.head); //Does this not work?
}

我运行 main() 中的代码:

int main() {
  SinglyList<int> test;
  for (int i=0; i<5; i++)
    test.add(i);
  test.print(); //This outputs 0 1 2 3 4
  SinglyList<int> test2 = test;
  test2.print(); //This should output 0 1 2 3 4 but outputs a bunch of garbage numbers
  return 0;
}

然后它崩溃了。我不完全确定问题出在哪里。是用拷贝构造函数还是copy方法?

关于重载赋值运算符,使用复制方法也不起作用,但是运行在重载中使用代码本身可以吗?

template<class T>
SinglyList<T>& SinglyList<T>::operator=(const SinglyList<T> &b) {
    //this->copy(b.head); <---This doesn't work
    Node *current = b.head;
    if (current->next==NULL) {
        this->add(current->x);
    } else while (current!=NULL) {
        this->add(current->x);
        current = current->next;
    }
    return *this;
}

class 的伴随代码:

template<class T>
class SinglyList {
protected:
    class Node {
    public:
        T x;
        Node *next;
        Node(T x0) {
            x = x0;
            next = NULL;
        }
    };
    Node *head;
    Node *tail;
    int n;
    SinglyList<T> copy(Node*);
public:
    SinglyList();
    SinglyList(const SinglyList<T>&);
    ~SinglyList() {
        Node *u = head;
        while (u != NULL) {
            Node *w = u;
            u = u->next;
            delete w;
        }
    };
    void add(T);
    SinglyList<T>& operator=(const SinglyList<T>&);
    void print();
};

免责声明:部分代码是从 Open Data Structures 中提取的,HW 将修改代码以向现有代码添加额外的功能。

有一些问题,最大的是无限递归。

您的复制构造函数调用 copy 函数,该函数 returns 一个新的值列表,这意味着它将被复制并调用复制构造函数。等等等等。使用 调试器 可以轻松检测到此问题。我建议你花点时间去 learn how to debug your programs.

通过正确初始化成员变量,您可以使用赋值运算符(如您所示)来实现复制构造函数,例如 *this = a;.

但是,我宁愿建议您修改 copy 函数以从另一个列表复制到 this 列表,而不是创建一个新列表并返回它。


关于那个赋值运算符...你必须考虑当前列表已经个节点的情况,你必须先删除它们。