const成员函数可以修改数据成员

时间:2016-04-20 19:02:01

标签: c++

问题:为什么const成员函数有时会修改数据成员,有时候不能修改数据成员?

解释:下面的代码摘自我工作基线中的工作代码。

我有一个Calculator类,它拥有一个名为“theLayout”的数据成员(下面定义的Header和Implementation)。计算器类有一个名为“Parms()”的const成员函数,它返回一个智能指针,该指针指向theLayout拥有的Parms对象(通过调用它自己的Parms()函数)。

计算器类有一个名为calculateStart()的const成员函数,它设置(即修改)从Calculator类中调用Parms()函数返回的引用。

这似乎与const的含义相矛盾。如果const成员函数无法修改this指针,那么为什么它可以在它拥有的其中一个数据成员(theLayout)上设置一个值?这不是“修改”Calculator实例的this指针,因此与const成员函数的含义相矛盾吗?这是否有效,因为theLayout是一个指针?

计算器类

//Header
class Calculator
{
public:
   Calculator();
   //ParmsPtr is refcounted smart pointer
   const ParmsPtr& parms() const {return theLayout->parms();} 

protected:
   void calculateStart() const; //Why does this work?
   //It seems more intuitive that this should be declared as:
   void calculateStart() //with no const modifier.

   Layout&  theLayout;
}

//Implementation
void Calculator::calculateStart() const
{
   parms()->setStart(1);
}

布局类

//Header
class Layout : public RefCountedObject
{
public:
   Layout();
   //ParmsPtr is refcounted smart pointer 
   inline const ParmsPtr& parms() const;

private:
   ParmsPtr theParms;
}

//Implementation
inline const ParmsPtr& Layout::parms() const
{
   if (!theParms)
   {
      Layout* nonConstThis = const_cast<Layout*>(this);
      ParmsPtr parms = new Parms();
      nonConstThis->setParms(parms);
   }

   return theParms;
}

2 个答案:

答案 0 :(得分:1)

  

计算器类有一个名为calculateStart()的const成员函数,它设置(即修改)从Calculator类中调用Parms()函数返回的引用。

是的,st.sorted( Map.Entry.<K, V>comparingByValue().reversed() ) .forEachOrdered(e -> result.put(e.getKey(), e.getValue())); 会修改计算器对象,考虑到其定义中的最终const限定符,这是意外的。

为什么?看看calculateStart()的定义;最后的inline const ParmsPtr& Layout::parms() const告诉编译器该函数不会修改const对象,尽管它实际上是这样。怎么样 ?通过错误地Layout将对象转换为非const对象;这就是常量被打破的地方,这就是为什么可以调用const_cast

这是一种不好的做法,尽管可能有一些理由这样做。在这种情况下,setParms()就是为了这个目的。

答案 1 :(得分:-2)

关键问题是,通过将start()声明为const,究竟是什么形成了const?答案是引用,而不是引用的

在您的示例中,在start()方法内,编译器将数据成员视为具有类型Layout const&amp;,这与const Layout&amp ;;不同。同样的事情适用于指针。如果您的数据成员是指针类型,编译器将看到类型为布局const *。