简体   繁体   中英

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

I'm trying to implement a copy constructor for a linked list. I've written a copy method that returns a list that's going to be used for the copy constructor and overloading the assignment operator:

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;
}

With the add() method used above here:

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++;
}

I've been trying to implement the copy constructor as so:

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

I run the code as such in 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;
}

Then it crashes. I'm not entirely sure what the problem is. Is it with the copy constructor or the copy method?

In regards to overloading the assignment operator, using the copy method doesn't work either but running the code itself in the overload works?

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;
}

Accompanying code of the 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();
};

Disclaimer: Some of this code was lifted from Open Data Structures and the HW was to modify the code to add extra features to the existing code.

There are a few problems, the biggest which is an infinite recursion.

Your copy-constructor call the copy function which returns a new list by value, meaning it will be copied and the copy-constructor will be called. And so on and so on. This issue would have been easily detected using a debugger . I suggest you take some time to learn how to debug your programs .

With proper initialization of the member variables, you could possibly use the assignment operator (as you show it) to implement the copy-constructor, like *this = a; .

However, I would rather recommend that you modify the copy function to copy from the other list into this list instead of creating a new list and returning it.


About that assignment operator... You have to think about the case when the current list already have nodes, you have to remove them first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM