C ++ const and mutable functions with the same name

Given the following code snippet.

#include <iostream> using namespace std; class Object { public: Object() {} void Print() const { cout << "const" << endl; } void Print() { cout << "mutable" << endl; } }; void print_obj(const Object& obj) { obj.Print(); } int main() { Object obj1; const Object obj2; Object*const pobj1 = &obj1; print_obj(obj1); print_obj(obj2); obj1.Print(); obj2.Print(); pobj1->Print(); return 0; } 

Output signal

 const const mutable const mutable 

I am wondering how C ++ decides which method to call when it encounters many mutable methods with the same name?

+4
source share
4 answers
 print_obj(obj1); print_obj(obj2); 

The called function is evaluated based on the cv determinant ( const / volatile ) of the passed object. Please note that cv qualifiers are considered when resolving function overloads.
If the passed object is const , a function is selected that receives the argument const . If the passed object is not a constant, a function is selected that takes a non-constant argument.


 obj1.Print(); obj2.Print(); pobj1->Print(); 

If the object is const , then only the const function can be called. If the object is not constant, then the non-const version is taught in the const version.

The rules are clearly indicated by the standard.

Reference:
C ++ 03 standard:
ยง13.3.1. Candidate functions and argument lists:

For non-static member functions, the parameter type of the implicit object is a "reference to cv X ", where X is the class of which the member is a member, and cv is the cv qualification on the member of the function declaration. [Example: for a const member function of class X it is assumed that the additional parameter is of type โ€œreference to const X โ€. ]

So, if the object is const , the compiler will select a version of the member function that has an implicit parameter object of a reference to the type const Object , which is a version of const Print() .

+7
source

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); 
+1
source

Remembering that for a regular object, if the version is not const , then the version is not const ; otherwise, the const version is selected. The following is the analysis:

 print_obj(obj1); // print_obj() receives const argument, so `const` is chosen print_obj(obj2); // same as above obj1.Print(); // obj1 is not const, so non-const version is chosen obj2.Print(); // obj2 is const, so must choose const version pobj1->Print(); // pobj1 is a const pointer pointing to non-const object, so non-const version is chosen 
+1
source

He would have preferred the const method not to be const const if they both did.

The same thing works for volatile, BTW.

-2
source

Source: https://habr.com/ru/post/1433933/


All Articles