我正在尝试编写一个打印函数,该函数按链表的相反顺序打印元素。只有当我用const声明函数为nonconst时,它才起作用——它不起作用,并抛出以下错误。
cannot convert 'this' pointer from 'const slist<int>' to 'slist<int> &'
我在下面看到了一些关于它的SO帖子从常量成员函数调用非常数成员函数以及与该链接相关的帖子,但我无法理解。如果有人能帮助我理解它
我的代码:给出错误:cannot convert 'this' pointer from 'const slist<int>' to 'slist<int> &'
void slist<T>::print_with_recursion() const
{
node<T>* head = _first;
print_reverse(head);
}
void slist<T>::print_reverse(node<T>* head)
{
if (head)
{
print_reverse(head->_next);
cout << head->_data << endl;
}
}
如果我删除const,我不会得到任何错误。此外,如果有更好的方法来实现按相反顺序打印链表,请给出函数定义print_with_recursion()const。
您的函数是常量,但调用非常量成员函数(print_reverse
)是不允许的。
没有理由不完全常量,因为您不需要更改对象的任何数据。尝试:
void slist<T>::print_with_recursion() const
{
const node<T>* head = _first;
print_reverse(head);
}
void slist<T>::print_reverse(const node<T>* head) const
{
if (head)
{
print_reverse(head->_next);
cout << head->_data << endl;
}
}
如果我删除const,我不会得到任何错误
这是最好的解决方案。您应该养成将任何不需要更改其状态的函数设置为const
成员函数的习惯。
针对您的特定问题,您可以将print_reverse
设置为非成员函数
template <typename T>
void print_reverse(node<T>* head)
{
if (head)
{
print_reverse(head->_next);
cout << head->_data << endl;
}
}
那么,就不必担心函数的const
性了。
我建议将std::ostream
作为函数的参数进行额外的更改。
template <typename T>
void print_reverse(node<T>* head,
std::ostream& out)
{
if (head)
{
print_reverse(head->_next, out);
out << head->_data << std::endl;
}
}
这里的问题是类成员函数有一个该类类型的隐藏参数。所以
void slist<T>::print_with_recursion() const
实际上是
void slist<T>::print_with_recursion(const slist<T> *) const
和
void slist<T>::print_reverse(node<T>* head)
是
void slist<T>::print_reverse(slist<T> *, node<T>* head)
因此,当你在print_with_recursion()
中时,这个指针是const slist<T> *
,当你调用print_reverse()
时,你试图将const
指针传递给一个需要非const
指针的函数。
您可以通过将print_reverse()
设置为const
来解决此问题,因为它将使用const slist<T> *
而不是slist<T> *
。将不会改变对象状态的函数标记为const
也是一个好主意。