使用模板链接列表类复制构造函数错误

时间:2015-02-12 15:40:24

标签: c++ copy-constructor singly-linked-list

我正在使用模板类对链接列表进行分配。

在我的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;
}

元素和next是Node类的公共变量。

请注意,由于此赋值的性质,我无法更改类定义,只能执行该类。

修改

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

2 个答案:

答案 0 :(得分:2)

问题是您尝试为const对象LinkedList<T>::getLeader()调用非const成员函数other

由于getLeader成员函数不修改对象,因此可以将其设为const:

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

如果另外,你还想防止调用者无意中修改返回的节点,也使返回类型为const:

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

在这种情况下,您必须相应地调整tmp的定义。

如果您无法使用getLeader签名解决上述问题(如您对问题的修改所示),则会保留这些选项(按优先顺序排列):

  • 使用可以处理const对象的LinkedList类的其他功能(例如迭代器),假设有这样的功能可用
  • 直接为head访问other数据成员,而不是使用getLeader成员函数
  • 在调用other之前使用const_cast抛弃getLeader的常量

答案 1 :(得分:0)

getLeader()的签名更改为const确实是&#34;好&#34;你的问题的解决方案(并且,为了遵守许多其他环境中使用的标准,它可能应该被命名为head() ...),但是有另一种方法来解决你的问题,因为你已经在控制班级本身。

由于您在课堂上这样做,您也可以访问私人成员 - 包括同一班级的其他实例的私人成员。如果你看看getLeader()做了什么,它可能就像这样 1

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

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

这意味着在您的复制构造函数/赋值运算符中,您可以直接访问other.head,而不是通过getLeader()执行此操作。只要您不尝试更改other.head的值,就应该没问题。


1)注意:未经测试。我把它写在我的头顶,所以它甚至可能无法编译。即使它没有编译,我也希望我的观点能够实现......