简体   繁体   中英

Copy Constructor Error With a Template Linked List Class

I am doing an assignment on linked lists using a template class.

In my main.cpp I should be able to create the list (which works) and create another list using either the assignment operator or the copy constructor. Here is my code:

template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& other)
{
    Node<T>* tmp = other.getLeader(); //LINE WHERE THE ERROR OCCURS

    for(int i = 0; tmp != NULL; i++)
    {
        insert(i, tmp->element);
        tmp = tmp->next;
    }
}

template <class T>
Node<T>* LinkedList<T>::getLeader()
{
    return head;
}

The error reads:

linkedList.C:61:6: error: passing ‘const LinkedList<int>’ as ‘this’ argument 
    of ‘Node<T>* LinkedList<T>::getLeader() [with T = int]’ 
    discards qualifiers [-fpermissive] tmp = other.getLeader();

Main.cpp:

int main()
{
    LinkedList<int> list;
    list.insert(0, 0);
    list.insert(1, 1);
    list.insert(2, 2);
    cout << list;

    LinkedList<int> list2(list);
    cout << list2;

    return 0;
}

element and next are public variables of the Node class.

Please note, that due to the nature of this assignment I cannot change the class definition only the implementation of the class.

EDIT:

template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& other) // I CANNOT CHANGE THIS
{
    // I CAN CHANGE THIS
}

The problem is that you try to call the non-const member function LinkedList<T>::getLeader() for a const object other .

Since the getLeader member function does not modify the object, you can make it const :

template <class T>
Node<T>* LinkedList<T>::getLeader() const

If additionally, you want to also prevent that the caller can inadvertently modify the returned node, also make the return type const :

template <class T>
const Node<T>* LinkedList<T>::getLeader() const

In that case, you'll have to adjust the definition of tmp accordingly.

If you cannot fix the above issue with the getLeader signature (as indicated by your edit of the question), you have these options left (in order of preference) :

  • use other functionality of the LinkedList class that can work on const objects (like an iterator eg.), assuming such functionality is available
  • access the head data member directly for other , instead of using the getLeader member function
  • use const_cast to cast away the const-ness of other before calling getLeader on it

Changing getLeader() 's signature to be const would indeed be the "good" solution to your problem (and, to adhere to standards used in many other contexts, it should probably have been named head() ...), but there is another way to solve your problem given that you're in control of the class itself.

Since you're doing this inside the class, you have access to private members as well - that includes private members of other instances of the same class. If you look at what getLeader() does, it's probably something like this 1 :

template<typename T>
class LinkedList {
private:
    Node<T>* head;

public:
    const Node<T>* getLeader() {
        return head;
    }
}

This means that in your copy constructor/assignment operator, you could access other.head directly, instead of doing it via getLeader() . As long as you don't try to change the value of other.head you should be fine.


1) Note: untested. I write this off the top of my head, so it might not even compile. I hope my point comes across even if it doesn't compile...

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