views:

130

answers:

3

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. 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?

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.

Why does it work this way?

+4  A: 

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.

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.

Greg Hewgill
OK, it would be the parameters. Thank you!
Hooked
+2  A: 

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. 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. 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).

Steve Jessop
A: 

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.

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.

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. 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. Since operator= is not const, a compiler error will be reported.

Cătălin Pitiș