tags:

views:

140

answers:

5

I'm wondering if a class's member function should be const if it calls other functions that modify its data members. A good example would be a public member function that uses private member functions to do the brunt of the work.

void Foo::Show() const { // Doesn't directly modify data members in this function
    ShowPig(); // One or all of these functions modify data members
    ShowCow();
    ShowBar();
}

Maybe not the best example, but you get the idea.

+11  A: 

Any Good compiler does not allow this. You should get the compiler error.

aJ
+6  A: 

The compiler should not allow you to do that. Example below.

//MS VC 2008
class Foo
{
  int m_iBar;

  void ThisIsConstFunc() const
  {
    m_iBar = 9; //error C2166: l-value specifies const object
    ThisIsNonConst(); //error C2662: 'Foo::ThisIsNonConst' : cannot convert 'this' pointer from 'const Foo' to 'Foo &'
  }

  void ThisIsNonConst() 
  {
    m_iBar = 9;
  }
};
Igor Zevaka
const can be casted away, though.
asveikau
The question then is not whether a constant method could/should call a non contant one, but rather how to explain that you are doing a `const_cast` (at all, and for that purpose in particular)
David Rodríguez - dribeas
@dribeas You are right, i finally 100% understand what the question was (and the accepted answer) after reading it for the fiftieth time.
Igor Zevaka
+4  A: 

If a function calls functions that modify certain data, then it should be said that the function itself modifies data. It just happens to be abstracted.

So no, that function should not be const.

GMan
+2  A: 

C++ provides the mutable keyword for the rare case that you actually want to allow this. And there are times where it happens, for instance if your function does not change the logical state of the object, but may modify one or more members of the object.

These cases are very rare. In the vast majority of cases you should mark the member function const if neither that function nor any function it calls modifies the state of the object.

Dan Olson
The number one case for mutable, IMO, is lazy evaluation. You can have a function that preforms an expensive operation once and caches the value. The cache, and guard variables, if any, should be mutable. This allows the lazily evaluated class to still declare the function as const, but still benefit from lazy evaluation.
KitsuneYMG
I read once a definition in the lines of 'a method should be constant if it does not modify the perceivable state, that is if all operations on the object will have the same effect before and after calling the constant method'. Mutexes are the first candidates for the mutable keyword, then there are others like cached results...
David Rodríguez - dribeas
There's the following argument about mutable: "if a function changes a state of a class, such as datamembers, but not in such way that its behavior will appear ANY different - thru its public interface, may it be const or not?And the accepted answer is YES. It may, and often should be const. There's a value in letting users specify that another function does not perform significant changes. For instance, statistics collection, database optimization, triggering some GC mechanism, cache optimizations, etc. For this, 'mutable' was invented and I find it useful.
Pavel Radzivilovsky
I use mutable a lot when I want to delay initialization of data members until they are accessed. This prevents that huge initialization delay seen in many applications. Also, the method is considered const except for the one instance where it initializes its data members.
Thomas Matthews
A: 

Yes, the compiler won't let you, as pointed out. Of course you can do it anyway but if the function needs to be const usually it's a bad idea. If it doesn't need to be const, don't just put it in there for no reason. There's really not much benefit to const and many potential serious problems, you just get forced into it at times.

Charles Eli Cheese