使用模板链表复制构造函数错误 Class
Copy Constructor Error With a Template Linked List Class
我正在使用模板 class 对链表进行赋值。
在我的 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 是节点 class 的 public 个变量。
请注意,由于这项任务的性质,我无法更改 class 定义,只能更改 class 的实现。
编辑:
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& other) // I CANNOT CHANGE THIS
{
// I CAN CHANGE THIS
}
问题是您尝试为 const 对象 other
.
调用非 const 成员函数 LinkedList<T>::getLeader()
由于getLeader
成员函数不修改对象,可以使它成为const :
template <class T>
Node<T>* LinkedList<T>::getLeader() const
如果另外,您还想防止调用者无意中修改 returned 节点,还要使 return 类型为 const :
template <class T>
const Node<T>* LinkedList<T>::getLeader() const
在这种情况下,您必须相应地调整 tmp
的定义。
如果您无法使用 getLeader
签名解决上述问题(如您对问题的编辑所示),您还有这些选项(按优先顺序):
- 使用
LinkedList
class 的其他功能,这些功能可用于 const 对象(例如迭代器),假设此类功能可用
- 直接为
other
访问 head
数据成员,而不是使用 getLeader
成员函数
- 在调用
getLeader
之前使用 const_cast
抛弃 other
的常量性
将 getLeader()
的签名更改为 const
确实可以 "good" 解决您的问题(并且,为了遵守许多其他情况下使用的标准,它可能应该已命名为 head()
...),但还有另一种方法可以解决您的问题,因为您可以控制 class 本身。
由于您是在 class 中执行此操作,因此您也可以访问私有成员 - 这包括相同 [=] 的 其他实例 的私有成员35=]。如果你看看 getLeader()
做了什么,它可能是这样的1:
template<typename T>
class LinkedList {
private:
Node<T>* head;
public:
const Node<T>* getLeader() {
return head;
}
}
这意味着在您的复制 constructor/assignment 运算符中,您可以直接访问 other.head
,而不是通过 getLeader()
进行访问。只要您不尝试更改 other.head
的值,您应该没问题。
1) 注意:未经测试。我把它写在脑海中,所以它甚至可能无法编译。我希望我的观点能够被理解,即使它没有编译...
我正在使用模板 class 对链表进行赋值。
在我的 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 是节点 class 的 public 个变量。
请注意,由于这项任务的性质,我无法更改 class 定义,只能更改 class 的实现。
编辑:
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& other) // I CANNOT CHANGE THIS
{
// I CAN CHANGE THIS
}
问题是您尝试为 const 对象 other
.
LinkedList<T>::getLeader()
由于getLeader
成员函数不修改对象,可以使它成为const :
template <class T>
Node<T>* LinkedList<T>::getLeader() const
如果另外,您还想防止调用者无意中修改 returned 节点,还要使 return 类型为 const :
template <class T>
const Node<T>* LinkedList<T>::getLeader() const
在这种情况下,您必须相应地调整 tmp
的定义。
如果您无法使用 getLeader
签名解决上述问题(如您对问题的编辑所示),您还有这些选项(按优先顺序):
- 使用
LinkedList
class 的其他功能,这些功能可用于 const 对象(例如迭代器),假设此类功能可用 - 直接为
other
访问head
数据成员,而不是使用getLeader
成员函数 - 在调用
getLeader
之前使用const_cast
抛弃other
的常量性
将 getLeader()
的签名更改为 const
确实可以 "good" 解决您的问题(并且,为了遵守许多其他情况下使用的标准,它可能应该已命名为 head()
...),但还有另一种方法可以解决您的问题,因为您可以控制 class 本身。
由于您是在 class 中执行此操作,因此您也可以访问私有成员 - 这包括相同 [=] 的 其他实例 的私有成员35=]。如果你看看 getLeader()
做了什么,它可能是这样的1:
template<typename T>
class LinkedList {
private:
Node<T>* head;
public:
const Node<T>* getLeader() {
return head;
}
}
这意味着在您的复制 constructor/assignment 运算符中,您可以直接访问 other.head
,而不是通过 getLeader()
进行访问。只要您不尝试更改 other.head
的值,您应该没问题。
1) 注意:未经测试。我把它写在脑海中,所以它甚至可能无法编译。我希望我的观点能够被理解,即使它没有编译...