从const函数调用非常量函数

calling non const function from const function

本文关键字:常量 函数 非常 函数调用 const      更新时间:2023-10-16

我正在尝试编写一个打印函数,该函数按链表的相反顺序打印元素。只有当我用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也是一个好主意。