All function overloading works in exactly the same way.
When considering a member function for overloading, it includes the implicit this parameter. If the function is declared const, then the parameter this const Object * . If the function is not const , then this Object * parameter. Since const qualifiers affect function overload rules, this means that a function const function also affects function overload rules.
In your specific example, print_obj(obj1) prints const , because print_obj() declared as accepting const Object& , which means that it will always call the version of const Print() . Same thing with print_obj(obj2) .
obj1.Print() outputs mutable because obj1 not const , so the Print() version is not const is the best match and is chosen to allow function overloading.
obj2.Print() prints const , because obj2 is const , so the version of const Print() is the only function that fits this function.
pobj1->Print() prints mutable because *pboj1 is not a const value, so the Print() version is not const for the overload resolution function.
The easiest way to think about what will happen if you just have
void Print(Object &obj); void Print(const Object &obj);
source share