Указатель this
Синтаксис
this |
Выражение this является prvalue выражением, значение которого — адрес неявного параметра объекта (объекта, для которого вызывается нестатический член-функция(до C++23)неявный член-функция объекта(с C++23)). Он может использоваться в следующих контекстах:
| (до C++17) |
| (с C++11) |
| 3) В инициализаторе по умолчанию члена. 4) В списке захвата лямбда-выражения. | (с C++11) |
Объяснение
this может связываться только с самым внутренним окружающим классом, даже если ссылка некорректна в текущем контексте:
class Outer
{
int a[sizeof(*this)]; // error: not inside a member function
unsigned int sz = sizeof(*this); // OK: in default member initializer
void f()
{
int b[sizeof(*this)]; // OK
struct Inner
{
int c[sizeof(*this)]; // error: not inside a member function of Inner
// 'this' is not associated with Outer
// even if it is inside a member function of Outer
};
}
};Тип this в член-функции класса X — X* (указатель на X). Если член-функция объявлена с последовательностью квалификаторов cv, тип this — cv X* (указатель на X с идентичными квалификаторами cv). Поскольку конструкторы и деструкторы не могут быть объявлены с квалификаторами cv, тип this в них всегда X*, даже при создании или удалении объекта const.
При использовании нестатического члена класса в любом контексте, где разрешено ключевое слово this, (тела нестатических член-функций, списки инициализаторов членов, инициализаторы членов по умолчанию), неявный this-> автоматически добавляется перед именем, создавая выражение доступа к члену (которое, если член является виртуальной функцией, приводит к виртуальному вызову функции).
В шаблонах классов this — зависимое выражение, и явный this-> может быть использован для принудительного создания зависимого выражения.
template<typename T>
struct B
{
int var;
};
template<typename T>
struct D : B<T>
{
D()
{
// var = 1; // error: 'var' was not declared in this scope
this->var = 1; // OK
}
};Во время создания объекта, если значение объекта или его подобъекта доступно через glvalue, которое не получено непосредственно или косвенно из указателя this конструктора, значение полученного объекта или подобъекта неопределено. Другими словами, указатель this не может быть алиасом в конструкторе:
extern struct D d;
struct D
{
D(int a) : a(a), b(d.a) {} // b(a) or b(this->a) would be correct
int a, b;
};
D d = D(1); // because b(d.a) did not obtain a through this, d.b is now unspecifiedМожно выполнить delete this;, если программа может гарантировать, что объект был выделен с помощью new, однако это делает все указатели на удалённый объект недействительными, включая сам указатель this. После того, как delete this; вернётся, такая член-функция не может ссылаться на члены класса (так как это подразумевает неявное разыменование this) и никакие другие член-функции не могут быть вызваны.
Это может быть использовано в член-функции указателя со счётом ссылок (например, std::shared_ptr)(с C++11) , ответственной за уменьшение счётчика ссылок, когда последняя ссылка на управляемый объект выходит из области видимости.
class ref
{
// ...
void incRef() { ++mnRef; }
void decRef() { if (--mnRef == 0) delete this; }
};Ключевые слова
Пример
class T
{
int x;
void foo()
{
x = 6; // same as this->x = 6;
this->x = 5; // explicit use of this->
}
void foo() const
{
// x = 7; // Error: *this is constant
}
void foo(int x) // parameter x shadows the member with the same name
{
this->x = x; // unqualified x refers to the parameter
// 'this->' required for disambiguation
}
int y;
T(int x) : x(x), // uses parameter x to initialize member x
y(this->x) // uses member x to initialize member y
{}
T& operator=(const T& b)
{
x = b.x;
return *this; // many overloaded operators return *this
}
};Отчёты об ошибках
Следующие отчёты об ошибках, меняющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение как опубликовано | Корректное поведение |
|---|---|---|---|
| CWG 760 | C++98 | при использовании this в вложенном классе, неопределённо, с каким классом он связанвложенным или окружающим |
this всегда связывается ссамым внутренним вложенным классом, независимо от того, находится ли он в нестатической член-функции |
| CWG 2271 | C++98 |
this мог быть алиасом при создании не-const объекта |
алиас также запрещён в этом случае |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/this