模板链表类的复制构造函数错误

Copy Constructor Error With a Template Linked List Class

本文关键字:复制 构造函数 错误 链表      更新时间:2023-10-16

我正在使用模板类对链表进行赋值。

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

element和next是Node类的公共变量。

请注意,由于此作业的性质,我不能仅更改类的实现来更改类的定义。

编辑:

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

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

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

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

此外,如果您还想防止调用者无意中修改返回的节点,也可以将返回类型设为const:

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

在这种情况下,您将不得不相应地调整tmp的定义。

如果您无法用getLeader签名解决上述问题(如您对问题的编辑所示),您可以选择以下选项(按偏好顺序):

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

getLeader()的签名更改为const确实是解决问题的"好"方法(而且,为了遵守许多其他上下文中使用的标准,它可能应该命名为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)注意:未经测试。我把这个写在脑子里,所以它甚至可能不会编译。我希望我的观点能得到理解,即使它没有编译