Все мы знаем, что this - указатель на объект, на котором сейчас находится контекст исполнения. Будь то метод, default member initializer или лямбда выражение. И вот есть в этих ваших интернетах такое мнение, что этот this - нулевой неявный аргумент метода и он передается в него в таком виде:
void Foo::bar(Foo * const this, Type1 param1, Type2 param2) {}То есть типа this - константный указатель.
Так наверное можно думать, но это не совсем правда. Точнее так. Действительно, this подразумевает под собой адрес неявного аргумента-объекта. Но нигде не написано, что он константный.
Да ему нельзя ничего присваивать. Например
void Foo::change(Foo *foo) { this = foo; }При компиляции кода появится примерно такая ошибка: lvalue required as left operand of assignment. Но если приглядеться, то ни про какой const там речь не идет. Ему не хватает lvalue слева.
Все потому что this - prvalue выражение. То есть можно даже сказать, что это и не указатель. Это выражение, значение которого равно адресу объекта. Оно не может быть использовано слева от знака равенства и у него нельзя взять адрес.
И именно поэтому ему нельзя ничего присваивать, а не потому что это константный указатель.
Но вот cv-квалификация метода может повлиять на cv-квалификацию указателя на объект. Тип this в обычном методе - Foo *(указатель на Foo). Однако для cv-квалифицированных методов this становится cv Foo *. То есть:
void Foo::ConstMemberFunction(Type1 param1, Type2 param2) const {
// this - const Foo *
this->field = param1; // Error!
}Сделано это, естественно, чтобы мы никак не могли изменить объект, на который указывает this, в константном методе.
Так что this - prvalue и точка!
Make points in your life. Stay cool.
#cppcore