[LC++]How to use const member functions correctly?

Carlo Wood carlo at alinoe.com
Sat Sep 22 02:20:05 UTC 2001


On Fri, Sep 21, 2001 at 12:30:58PM +0930, Mark Phillips wrote:
> My understanding of const member functions, is that by declaring
> it constant, you are giving a guarentee that it will not change
> the internals of the object.

That is correct.  You might (also) want to read a memo I once wrote
called 'Understanding the const qualifier':
http://www.xs4all.nl/~carlo17/c++/const.qualifier.html

That doesn't go deeply into member functions though, so I'll address
the rest of your mail too.

> But I have a problem.  What if I have a member function which has
> a parameter passed by reference (non-constant).  Passing by
> reference allows the function to modify an external variable.

Not really, all attributes should be private or protected.
More correctly stated therefore is that you will be able to call non-const
member functions (on top of calling the const member functions that would
have been possible when you'd pass a const reference).

> Normally this external variable will be unrelated to the internals
> of the object, so for most of the time, this function may be thought
> of as const.  But what if somewhere, this function is used to modify
> an internal variable of the object --- by passing it in as the
> reference parameter --- then all of a sudden the function is non-const!
> 
> What should be done in this situation?  Should I declare it const, and
> rely on the programmer to take care not to pass in the wrong parameter?
> 
> If I don't make it const, then I can't call the function from other
> const member functions, even though I know that in this case it is
> not changing internals.
> 
> What to do??

The ONLY meaning of `const' for member functions is that you are allowed
to call it for constant `this' objects.  So, you want to keep it const.

For example:

class Mark {
private:
  int i;
public:
  void f(Mark& mark) const;
};

and

void Mark::f(Mark& mark) const
{
  mark.i = 0;
}

is technically perfectly ok concerning the `const'-ness of `f'.

If for some other reason you never want `f' to change the current
object, then the right thing to do would be to add an assertion:

#include <cassert>
...

void Mark::f(Mark& mark) const
{
  assert(&mark != this);
  mark.i = 0;
}

There is a very common case where this is relevant and you don't
even need to add an assertion, but a special case for `this'
being equal the passed object: assignment operators.

Please read
http://users.utu.fi/sisasa/oasis/cppfaq/assignment-operators.html

specifically 12.3.

(You should read the FAQ completely anyway before asking questions
 on a formum like this ;).

-- 
Carlo Wood <carlo at alinoe.com>



More information about the tuxCPProgramming mailing list