从 const 函数调用非 const 函数

calling non const function from const function

我正在尝试编写一个打印函数,它以倒序打印 linked 列表的元素。它仅在我用 const 声明非 const 函数时有效,它不起作用并抛出以下错误。

cannot convert 'this' pointer from 'const slist<int>' to 'slist<int> &'

关于它,我看到了一些 SO post,如下所示 Call a non-const member function from a const member function 以及与 link 相关联的 post,但我无法理解它。如果有人能帮我理解一下

我的代码: 给出错误: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,我不会收到任何错误。此外,如果有更好的方法来实现以相反顺序打印 linked 列表,请给出函数定义 print_with_recursion() const,请提出建议。

if I remove const I dont get any error

这是最好的解决方案。您应该养成将任何不需要更改其状态的函数设为 const 成员函数的习惯。

针对您的特定问题,您可以将 print_reverse 设为非成员函数

template <typename T>
void print_reverse(node<T>* head)
{
    if (head) 
    {
        print_reverse(head->_next);
        cout << head->_data << endl;
    }
}

那么,就不用担心函数的const-ness了。

我建议将 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;
    }
}

这里的问题是 class 成员函数有一个 class 类型的隐藏参数。所以

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() 时,this 指针是一个 const slist<T> * 并且当你调用 print_reverse() 时,你试图将那个 const 指针传递给一个期望的函数非 const 指针。

您可以通过设置 print_reverse() const 来解决这个问题,因为这样它将需要 const slist<T> * 而不是 slist<T> *。将不会更改对象状态的函数标记为 const.

也是一个好主意

你的函数是 const 但调用了一个非常量成员函数 (print_reverse),这是不允许的。

没有理由不将其中的任何一个完全设为 const,因为您不需要更改对象的任何数据。请尝试:

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