const before parameter vs const after function name c++

jazzybazz picture jazzybazz · Apr 14, 2013 · Viewed 66k times · Source

What is the difference betweeen something like this

friend Circle copy(const Circle &);

and something like this

friend Circle copy(Circle&) const;

I know const after the function is used to tell the compiler that this function won't attempt to change the object it is called on, what about the other one?

Answer

Andy Prowl picture Andy Prowl · Apr 14, 2013

The first form means that the (state of the) Circle object bound to the reference which is the parameter of the copy() function will not be altered by copy() through that reference. The reference is a reference to const, so it won't be possible to invoke member functions of Circle through that reference which are not themselves qualified as const.

The second form, on the other hand, is illegal: only member functions can be const-qualified (while what you are declaring there is a global, friend function).

When const qualifies a member function, the qualification refers to the implicit this argument. In other words, that function will not be allowed to alter the state of the object it is invoked on (the object pointed to by the implicit this pointer) - with the exception of mutable objects, but that's another story.

To say it with code:

struct X
{
    void foo() const // <== The implicit "this" pointer is const-qualified!
    {
        _x = 42; // ERROR! The "this" pointer is implicitly const
        _y = 42; // OK (_y is mutable)
    }

    void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
    {
        obj._x = 42; // OK! obj is a reference to non-const
        _x = 42; // ERROR! The "this" pointer is implicitly const
    }

    void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
    {
        obj._x = 42; // ERROR! obj is a reference to const
        obj._y = 42; // OK! obj is a reference to const, but _y is mutable
        _x = 42; // OK! The "this" pointer is implicitly non-const
    }

    int _x;
    mutable int _y;
};