对我感兴趣的帖子发表评论:
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正确性很重要,所以我想我希望编译器反对重载,因为一个变异,一个不变。
为什么这样做?
答案 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,因此将报告编译器错误。