TL;DR: to ensure that object isn't modified in function and to save one copy operation.
Only const
methods may be called for const
objects, and that methods couldn't alter state of an object:
class A {
int i = 10;
mutable int j = 10; // Explicitly allowed to change even for const objects
public:
void f() { ++i; } // OK: non-const function changes object
void g() const { ++i; } // Error: const function changes object
int h() const { return i; } // OK: const function doesn't change object
int s() const { return ++j; } // OK: const function changes mutable field
};
void foo(const A& a) {
a.f(); // Error: only const methods are allowed
a.g(); a.h(); a.j(); // OK
}
As you can see, there is no clean way to modify field i
from function foo
, but you can read A
fields with h()
and s()
methods.
You can also ensure that your local object isn't modified by callee function by passing copy to it:
void foo(A a);
bool is_pal(std::string s);
But copying may be expensive, so you have to pass it by reference:
void foo(A& a);
bool is_pal(std::string& s);
And to ensure that object will have same state it had before calling your function you have to add const
qualifier to it. This idiom is explained in Scott Meyers’ book, Effective C++, Third Edition, "Item 20: Prefer pass-by-reference-to-const to pass-by-value."