简体   繁体   English

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

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

A comment to one of my posts interested me: 对我的其中一篇帖子的评论使我感兴趣:

Me too . 我也是 I also give accessors/mutators the same name. 我也给访问者/更改者同一个名字。

I was wondering about this, because I have always used setBar(int bar) instead of a mutator named the same thing. 我对此很疑惑,因为我一直使用setBar(int bar)代替同名的mutator。 I want to know: can the compiler determine based on a const identifier what mutates at runtime, or can it use the same function name because it has a parameter? 我想知道:编译器可以基于const标识符确定运行时会发生什么变化,还是可以使用相同的函数名,因为它具有参数?

Will this compile fine: 可以编译吗:

class Foo
{
   int bar_;

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

Or do I have to do this (I realize I should be doing this anyways, just run with me on this): 还是我必须这样做(我意识到无论如何我都应该这样做,只要和我一起运行):

int bar() const { return bar_; }

I don't know which is which. 我不知道是哪个。 Const correctness is important, so I think I would want the compiler to object to the overloading since one mutates and one does not. const的正确性很重要,因此我认为我希望编译器反对重载,因为一个突变而另一个则不会。

Why does it work this way? 为什么这样工作?

The first thing the compiler looks at is the number and type of parameters you're passing to the function. 编译器首先查看的是传递给函数的参数的数量和类型。 This resolves the overload on bar before it even needs to look at const -ness. 这可以解决bar上的重载,甚至不需要查看const -ness。

If you fail to mark bar() as const , the compiler will inform you of this the first time you attempt to call bar() on a const instance of the object. 如果您未能将bar()标记为const ,则在您首次尝试在对象的const实例上调用bar()时,编译器会通知您。

The compiler will not prevent you from writing a non-const member function which in fact doesn't mutate the object. 编译器不会阻止您编写实际上不会使对象变异的非常量成员函数。 That's not a breach of const-correctness, which only ensures that objects are not mutated via const references. 这并不违反const正确性,后者只能确保对象不会通过const引用进行变异。 The principle here is that const says the function may not mutate, and non-const means the function is free to mutate if it wants to. 此处的原理是const表示该函数不能进行更改,而非const表示该函数可以随意进行更改。 There is no way to promise to mutate, and have the compiler enforce that: I think this would be too vague a guarantee to be of any use to callers. 没有办法保证会发生突变,而让编译器强制这样做:我认为这对于保证调用者没有任何用处的保证太含糊。

As Greg says, the compiler will object when you try to call a non-const member function on a const object (again, it's irrelevant whether it in fact mutates. The only important thing is whether it's declared const). 正如Greg所说的,当您尝试在const对象上调用非const成员函数时,编译器将成为对象(再次,实际上是否突变无关紧要。唯一重要的是是否将其声明为const)。

For an easier understanding, consider that compiler assumes that an object will be changed if a non-const method will be called for that object. 为了更容易理解,请考虑编译器假定,如果为该对象调用非const方法,则该对象将被更改。

So in a const method, if you call a non-const method for one of the data members or another non-const method of the class, the compiler will signal an error. 因此,在const方法中,如果您为数据成员之一或类的另一个非const方法调用非const方法,则编译器将发出错误信号。

You can consider operators as methods as well (I know, you can define some operators as friend functions, not as methods, but for simplifcation...). 您也可以将运算符视为方法(我知道,您可以将某些运算符定义为友好函数,而不是方法,而是为了简化...)。 For example, the assignment operator (operator=) is by default non-const. 例如,赋值运算符(operator =)默认为非常量。 That means if you do something like 这意味着如果您做类似的事情

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

The compiler will consider that you called the assignment operator of classMember, which, inside a const method is a const object. 编译器会认为您调用了classMember的赋值运算符,该运算符在const方法内部是const对象。 Since operator= is not const, a compiler error will be reported. 由于operator =不是const,将报告编译器错误。

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

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