从const函数调用非const函数

时间:2015-11-03 20:25:04

标签: c++ linked-list const

我正在尝试编写一个打印函数,它以链接列表的相反顺序打印元素。它仅在我用const声明函数non-const时才起作用它不起作用并抛出错误。

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

我在下面看到的关于它的SO帖子很少 Call a non-const member function from a const member function 和该链接相关的帖子,但我无法理解。如果有人可以帮助我理解它

我的代码: 给出错误: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,请做一下建议。

3 个答案:

答案 0 :(得分:3)

你的函数是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;
    }
}

答案 1 :(得分:2)

  

如果我删除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;
    }
}

答案 2 :(得分:0)

这里的问题是类成员函数具有该类类型的隐藏参数。所以

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指针传递给期望非{的函数{1}}指针。

您可以通过制作const print_reverse()来解决此问题,因为它需要const而不是const slist<T> *。标记不会将对象状态更改为slist<T> *的函数也是一个好主意。