繁体   English   中英

编译器如何确定哪些成员函数发生突变?

[英]How does the compiler determine which member functions mutate?

对我的其中一篇帖子的评论使我感兴趣:

我也是 我也给访问者/更改者同一个名字。

我对此很疑惑,因为我一直使用setBar(int bar)代替同名的mutator。 我想知道:编译器可以基于const标识符确定运行时会发生什么变化,还是可以使用相同的函数名,因为它具有参数?

可以编译吗:

class Foo
{
   int bar_;

   public:
      int bar() { return bar_; }
      void bar(int bar) { bar_ = bar; }
}

还是我必须这样做(我意识到无论如何我都应该这样做,只要和我一起运行):

int bar() const { return bar_; }

我不知道是哪个。 const的正确性很重要,因此我认为我希望编译器反对重载,因为一个突变而另一个则不会。

为什么这样工作?

编译器首先查看的是传递给函数的参数的数量和类型。 这可以解决bar上的重载,甚至不需要查看const -ness。

如果您未能将bar()标记为const ,则在您首次尝试在对象的const实例上调用bar()时,编译器会通知您。

编译器不会阻止您编写实际上不会使对象变异的非常量成员函数。 这并不违反const正确性,后者只能确保对象不会通过const引用进行变异。 此处的原理是const表示该函数不能进行更改,而非const表示该函数可以随意进行更改。 没有办法保证会发生突变,而让编译器强制这样做:我认为这对于保证调用者没有任何用处的保证太含糊。

正如Greg所说的,当您尝试在const对象上调用非const成员函数时,编译器将成为对象(再次,实际上是否突变无关紧要。唯一重要的是是否将其声明为const)。

为了更容易理解,请考虑编译器假定,如果为该对象调用非const方法,则该对象将被更改。

因此,在const方法中,如果您为数据成员之一或类的另一个非const方法调用非const方法,则编译器将发出错误信号。

您也可以将运算符视为方法(我知道,您可以将某些运算符定义为友好函数,而不是方法,而是为了简化...)。 例如,赋值运算符(operator =)默认为非常量。 这意味着如果您做类似的事情

void MyClass::MyConstMethod() const
{
   classMember = value;
}

编译器会认为您调用了classMember的赋值运算符,该运算符在const方法内部是const对象。 由于operator =不是const,将报告编译器错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM