编译器如何确定哪些成员函数变异?

时间:2009-08-05 00:55:36

标签: c++ compiler-construction overloading

对我感兴趣的帖子发表评论:

  

Me too。我也给访问者/ mutator同名。

我对此感到疑惑,因为我总是使用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正确性很重要,所以我想我希望编译器反对重载,因为一个变异,一个不变。

为什么这样做?

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

编译器不会阻止你编写一个非const成员函数,它实际上不会改变对象。这并不违反const-correctness,它只能确保对象不会通过const引用进行变异。这里的原则是const表示函数可能不会变异,而非const表示函数可以随意变异。没有办法承诺变异,并让编译器强制执行:我认为这对于对调用者有任何用处的保证太过模糊。

正如Greg所说,当你试图在const对象上调用非const成员函数时,编译器会反对(同样,它实际上是否变异无关紧要。唯一重要的是它是否被声明为const)。

答案 2 :(得分:0)

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

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

您也可以将运算符视为方法(我知道,您可以将某些运算符定义为友元函数,而不是作为方法,但为了简化...)。例如,赋值运算符(operator =)默认为非const。这意味着如果您执行类似

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

编译器会认为你调用了classMember的赋值运算符,它在const方法中是一个const对象。由于operator =不是const,因此将报告编译器错误。