2015-02-12 4 views
0

Я выполняю задание по связанным спискам с использованием класса шаблона.Ошибка создания конструктора с шаблоном Связанный список Класс

В моем main.cpp я должен иметь возможность создать список (который работает) и создать другой список, используя либо оператор присваивания, либо конструктор копирования. Вот мой код:

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

Ошибка гласит:

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

элемент и рядом общественные переменные класса Node.

Обратите внимание, что из-за характера этого присвоения я не могу изменить определение класса только для реализации класса.

EDIT:

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

Вы используете 'new', чтобы сделать глубокую копию вставить? У вас по умолчанию 'head' на' nullptr'? Изменить: это не связано с вашей ошибкой компилятора, просто мое собственное назидание. – AndyG

+2

Ваша ошибка в том, что 'getLeader()' не const. Исправьте это. – AndyG

+0

Боковое примечание. Я приветствую это в вашем конструкторе копирования, вы не переопределили код в своей функции 'insert' и вместо этого повторно использовали его. Слишком много новичков совершают ошибку, переписывая всю функциональность «insert» в своем конструкторе копирования. – PaulMcKenzie

ответ

2

Проблема заключается в том, что вы пытаетесь вызвать неконстантные функции члена LinkedList<T>::getLeader() для константного объекта other.

Поскольку функция getLeader члена не изменяет объект, вы можете сделать это ПОСТОЯННЫМ:

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

Если дополнительно, вы также хотите предотвратить, что абонент может непреднамеренно изменить возвращаемый узел, а также сделать возврат Тип конструкции:

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

в этом случае вам придется изменить определение tmp соответственно.

Если вы не можете решить вышеуказанную проблему с getLeader подписи (как указано правкой вопроса), то есть эти варианты остались (в порядке предпочтения):

  • использование другой функциональность LinkedList класс, который может работать на константных объектов (как, например, итератора.), предполагая, что такие функциональные возможности доступны
  • доступа член head данных непосредственно для other, вместо того чтобы использовать функцию getLeader члена
  • использование const_cast откинуть на константный-ность other перед вызовом getLeader на нем
+0

Поскольку я не могу изменить функцию, как вы сказали (файл .h будет заменен в процессе маркировки), есть ли другой способ реализовать конструктор копирования без необходимости добавлять что-то к имени функции? Спасибо за ответ –

+0

Я не понимаю, как вы можете изменить конструктор, но не другую функцию-член. Но при условии, что у вас есть свои причины, вам придется сделать объект «другой» неконстантным (либо путем определения параметра конструктора как такового, либо путем отбрасывания константы). Но предпочитайте решение, представленное в моем ответе. –

+0

Я также предпочитаю ваш метод. Позвольте мне указать, что я могу изменить, а что нет. См. Редактирование в вопросе –

0

Изменение getLeader() «s подпись быть const действительно будет„хорошим“решением вашей проблемы (и придерживаться стандартов, используемых во многих в других контекстах, вероятно, это должно было быть названо head() ...), но есть другой способ решить вашу проблему, учитывая, что вы контролируете сам класс.

Поскольку вы делаете это внутри класса, у вас есть доступ к закрытым членам, а также к частным членам других экземпляров того же класса.Если вы посмотрите на то, что getLeader() делает, это, вероятно, что-то вроде этого :

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

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

Это означает, что в вашем оператора конструктор/назначения копирования, вы можете получить доступ к other.head непосредственно, вместо того, чтобы делать это с помощью getLeader(). Пока вы не пытаетесь изменить значение other.head, все должно быть хорошо.


1) Примечание: непроверено. Я пишу это с головы, поэтому он даже не компилируется. Я надеюсь, что моя точка натолкнется, даже если она не скомпилируется ...

Смежные вопросы