const函数中的成员赋值

时间:2009-11-25 12:09:44

标签: c++ function const variable-assignment member

我有一个类成员 myMember ,它是一个 myType 指针。我想在声明为const的函数中分配此成员。我这样做:

void func() const
{
     ...
     const_cast<myType*>(myMember) = new myType();
     ...
}

这样做在VC ++中工作正常,但是GCC给出了错误消息“左值作为赋值的左值”。

使成员可变允许我简单地删除const_cast并分配值。但是,我并不完全确定这会产生其他副作用。

我可以指定我的会员,而不必让会员变成可变的吗?怎么样?在使成员变得可变方面有任何副作用吗?

5 个答案:

答案 0 :(得分:17)

此方案 - 封装的内部状态更改不会影响外部状态(例如缓存结果) - 正是mutable关键字的用途。

答案 1 :(得分:8)

代码在VC ++中实际上不起作用 - 你没有更新值(或者至少它不应该),因此来自GCC的警告。正确的代码是

const_cast<myType*&>(myMember) = new myType();

或[来自其他回复,谢谢:P]:

const_cast<ThisType*>(this)->myMember = new myType();

有效地使它变为可变意味着你在const_cast成员函数中得到隐式const,这通常是当你发现自己在const_cast上加载this时需要注意的事情。 {1}}。除此之外,没有“使用可变的副作用”。

正如你可以从围绕这个问题的激烈辩论中看到的那样,对mutable和许多const_cast的使用绝对是你代码中难闻气味的症状。从概念的角度来看,抛弃常量或使用mutable可能会产生更大的影响。在某些情况下,正确的做法可能是将方法更改为非const,即拥有它正在修改状态的事实。

这一切都取决于你的上下文中的const正确性有多重要 - 你不想最终只是像小精灵一样缩小mutable以使东西工作,但是mutable是用于该成员不是该对象的可观察状态的一部分。最严格的const-correctness视图会认为对象的状态不能被修改(例如,如果你的实例在ROM中,这可能是关键的......) - 在这种情况下你不需要任何constness迷路了。在其他情况下,您可能将某个外部状态存储在对象的某个位置 - 例如,在决定是否合适时还需要考虑特定于线程的缓存。

答案 2 :(得分:6)

const_cast几乎总是设计失败的标志。在您的示例中,func()不应为const,或myMember应为mutable

func()的来电者希望她的对象不会改变;但这意味着“不要以她能注意到的方式改变”;这是,不要改变它的外部状态。如果更改myMember不会更改对象外部状态,则mutable关键字的用途是什么;否则,func()不应该是const,因为你会背叛你的功能保证。

请记住,mutable不是一种循环正确性的机制;它是一种改进它的机制。

答案 3 :(得分:5)

class Class{
int value;
void func()const{
const_cast<Class*>(this)->value=123;
}
};

答案 4 :(得分:1)

史蒂夫吉尔罕写道,mutable是你问题的正确(和简短)答案。我只想给你一个不同方向的暗示。 也许你的szenario可以使用一个(或多个)接口? 也许您可以通过以下示例来理解它:

class IRestrictedWriter // may change only some members
{
public:
  virtual void func() = 0; 
}

class MyClass : virtual public IRestrictedWriter
{
public:
  virtual void func()
  {
    mValueToBeWrittenFromEverybody = 123; 
  }

  void otherFunctionNotAccessibleViaIRestrictedWriter()
  {
    mOtherValue1 = 123;
    mOtherValue2 = 345;
  }

  ...   
}

所以,如果你传递给IRestrictedReader *而不是const MyClass *的某个函数,它可以调用func,从而更改mValueToBeWrittenFromEverybody,而mOtherValue1就是“常量”。

。我发现mutable总是有点破解(但有时会使用它)。