从const成员函数调用非const成员函数

时间:2010-10-28 21:06:13

标签: c++ const

我想知道是否可以从const成员函数调用非const成员函数。在下面的示例中,First给出了编译器错误。我理解为什么它会出错,我想知道是否有办法解决它。

class Foo
{
   const int& First() const
   {
         return Second();
   }

   int& Second()
   {
        return m_bar;
   }

   int m_bar;
}

我真的不想讨论这样做的智慧,我很好奇它是否可能。

7 个答案:

答案 0 :(得分:31)

return (const_cast<Foo*>(this))->Second();

然后静静地哭。

答案 1 :(得分:10)

可能

const int& First() const 
{ 
    return const_cast<Foo*>(this)->Second(); 
}

int& Second() { return m_bar; }

我不推荐这个;这是丑陋和危险的(使用const_cast是危险的。)

最好将尽可能多的常用功能移动到辅助函数中,然后让const和非const成员函数尽可能少地工作。

对于像这样的简单访问器,从两个函数中return m_bar;和从另一个函数调用一个函数一样容易。

答案 2 :(得分:3)

根据const的定义,函数不应修改对象的状态。但如果它调用另一个非const成员,则对象的状态可能会被更改,因此不允许这样做。

我知道你说你不想听到这个,但我认为这对其他人来说很重要。

答案 3 :(得分:3)

const成员方法的限制来自编译时。如果你可以欺骗编译器,那么是的。

class CFoo
{ 
public:
    CFoo() {m_Foo = this;}
    void tee();

    void bar() const 
    { 
        m_Foo->m_val++;  // fine 
        m_Foo->tee();    // fine
    }
private:
   CFoo * m_Foo;
   int    m_Val;  

};

这实际上废除了const成员函数的目的,所以在设计新类时最好不要这样做。知道有一种方法可以做到这一点是没有害处的,特别是它可以用来解决这些在const成员函数概念上没有很好设计的旧类。

答案 4 :(得分:2)

const上的重载:

const int& Second() const
{
    return m_bar;
}

您可以添加此方法并保留原始的非const版本。

答案 5 :(得分:1)

迭代器在此类似,并进行了一项有趣的研究。

const迭代器通常是“非常量”迭代器的基础,并且您经常会发现const_cast<>()或C样式转换用于从子类中删除带有子代中访问器的const。

编辑: 评论是

  

我有一个zip迭代器,其中const一个继承自非const

这通常是错误的遗产结构(如果你说的是我认为你的意思),原因是孩子的限制不应该比父母少。

说你有一些算法采用你的zip迭代器,是否适合将const迭代器传递给非const?

如果你有一个const容器,只能问它一个const迭代器,但是const迭代器是从迭代器派生出来的,所以你只需要使用父对象上的特性来进行非const访问。

以下是传统stl模型

之后的建议继承的快速概述
class ConstIterator: 
    public std::_Bidit< myType, int, const myType *, const mType & >
{
  reference operator*() const { return m_p; }
}

class Iterator : public ConstIterator 
{
  typedef ConstIterator _Mybase;
  // overide the types provided by ConstIterator
  typedef myType * pointer;
  typedef myType & reference;

  reference operator*() const
  { 
    return ((reference)**(_Mybase *)this);
  }
}

typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
typedef std::reverse_iterator<Iterator> ReverseIterator;

答案 6 :(得分:0)

我发现自己试图调用一个继承的非const成员函数,但由于我使用的API,它实际上是const。最后,我找到了一个不同的解决方案:重新协商API,以便我继承的函数是正确的const。

并不总是可以协商对其他人功能的更改,但在可能的情况下这样做似乎比需要使用const_cast更清晰,更好,并且它也有利于其他用户。