C ++ const и изменяемые функции с одинаковым именем

Учитывая следующий кусок кода.

#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;
}

Выход

const
const
mutable
const
mutable

Мне интересно, как C ++ решает, какой метод вызывать, когда сталкивается со многими изменяемыми методами с одинаковыми именами?

4

Решение

print_obj(obj1);
print_obj(obj2);

Вызываемая функция оценивается на основе резюме-классификатор(const/volatile) пропущенного объекта. Обратите внимание, что CV-классификаторы учитываются при разрешении перегрузки функции.
Если переданный объект const, функция получения const Аргумент выбран. Если переданный объект неконстантный, то выбирается функция, получающая неконстантный аргумент.


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

Если объект const тогда только позвони const функция-член может быть вызвана.
Если объект неконстантный, то неконстантная версия преферрируется над const версия.

Правила четко определены стандартом.

Ссылка:
Стандарт C ++ 03:
§13.3.1 Функции-кандидаты и списки аргументов:

Для нестатических функций-членов тип неявного параметра объекта — «ссылка на cv». X» где X это класс, членом которого является функция, а cv является квалификацией cv в объявлении функции-члена. [Пример: для константной функции-члена класса Xпредполагается, что дополнительный параметр имеет тип «ссылка на const X». ]

Так что если объект const компилятор выберет версию функции-члена, которая имеет неявный объектный параметр типа ссылка на const Object которая является постоянной версией Print(),

7

Другие решения

Таким же образом работает перегрузка всех функций.

При рассмотрении функции-члена для перегрузки, она включает в себя неявное this параметр. Если функция объявлена constтогда this параметр const Object *, Если функция не const тогда this параметр Object *, поскольку const квалификаторы влияют на правила перегрузки функций, это означает, что constФункциональность также влияет на правила перегрузки функций.

В вашем конкретном примере print_obj(obj1) печать const так как print_obj() объявлен как принимающий const Object&Это означает, что он всегда будет вызывать const версия Print(), То же самое с print_obj(obj2),

obj1.Print() печать mutable так как obj1 не является constследовательно, неconst версия Print() лучше подходит и выбирается для разрешения перегрузки функции.

obj2.Print() печать const так как obj2 является const, Следовательно const версия Print() это единственная перегрузка функции, которая подходит.

pobj1->Print() печать mutable так как *pboj1 это неconst значение, так что неconst версия Print() выбран для разрешения перегрузки функции.

Самый простой способ думать об этом, что бы произошло, если бы вы просто

void Print(Object &obj);
void Print(const Object &obj);
1

Имея в виду, что для нормального объекта, если неconst версия доступна, то неconst версия выбрана; иначе const версия выбрана. Ниже приведен анализ:

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

Было бы предпочтительнее, чтобы метод const был неконстантным, если бы оба метода это делали

То же самое работает для летучих, кстати.

-2
По вопросам рекламы [email protected]