The
this
pointer
Содержание |
Синтаксис
this
|
|||||||||
Выражение this является prvalue выражением , значение которого представляет собой адрес неявного параметра объекта (объекта, для которого вызывается неявная функция-член). Оно может появляться в следующих контекстах:
|
3)
Внутри
default member initializer
.
4)
Внутри
capture list
лямбда-выражения.
|
(since C++11) |
Объяснение
this может связываться только с самым внутренним объемлющим классом своего появления, даже если появление недопустимо в контексте:
class Outer { int a[sizeof(*this)]; // Ошибка: не внутри функции-члена unsigned int sz = sizeof(*this); // OK: в инициализаторе члена по умолчанию void f() { int b[sizeof(*this)]; // OK struct Inner { int c[sizeof(*this)]; // Ошибка: не внутри функции-члена Inner // “this” не связан с Outer // даже если находится внутри функции-члена Outer }; } };
Тип
this
в функции-члене класса
X
равен
X*
(указатель на X). Если функция-член
объявлена с последовательностью cv-квалификаторов
cv
, тип
this
равен
cv
X*
(указатель на аналогично cv-квалифицированный X). Поскольку конструкторы и деструкторы не могут быть объявлены с cv-квалификаторами, тип
this
в них всегда
X*
, даже при создании или уничтожении константного объекта.
В шаблонах классов, this является зависимым выражением , и явное использование this - > может использоваться для принудительного преобразования другого выражения в зависимое.
template<typename T> struct B { int var; }; template<typename T> struct D : B<T> { D() { // var = 1; // Ошибка: "var" не объявлен в этой области видимости this->var = 1; // OK } };
При конструировании объекта, если значение объекта или любого из его подобъектов доступно через glvalue, которое не получено, прямо или косвенно, из this указателя конструктора, значение объекта или подобъекта, полученное таким образом, является неопределённым. Другими словами, указатель this не может быть алиасирован в конструкторе:
extern struct D d; struct D { D(int a) : a(a), b(d.a) {} // b(a) или b(this->a) были бы корректны int a, b; }; D d = D(1); // поскольку b(d.a) не получило a через this, d.b теперь имеет неопределённое значение
Возможно выполнение
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; // то же самое, что this->x = 6; this->x = 5; // явное использование this-> } void foo() const { // x = 7; // Ошибка: *this является константным } void foo(int x) // параметр x скрывает член с тем же именем { this->x = x; // неквалифицированный x ссылается на параметр // «this->» требуется для устранения неоднозначности } int y; T(int x) : x(x), // использует параметр x для инициализации члена x y(this->x) // использует член x для инициализации члена y {} T& operator=(const T& b) { x = b.x; return *this; // многие перегруженные операторы возвращают *this } };
Отчеты о дефектах
Следующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| CWG 760 | C++98 |
когда
this
используется во вложенном классе, было
не определено, ассоциируется ли он с вложенным классом или с объемлющим классом |
this
всегда ассоциируется с
самым внутренним вложенным классом, независимо от того, находится ли он в нестатической функции-члене |
| CWG 2271 | C++98 |
this
мог быть алиасирован при
создании неконстантного объекта |
алиасинг также
запрещен в этом случае |
| CWG 2869 | C++98 |
было неясно, может ли
this
использоваться в
статической функции-члене неассоциированного класса |
прояснено |