Namespaces
Variants

The this pointer

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Содержание

Синтаксис

this

Выражение this является prvalue выражением , значение которого представляет собой адрес неявного параметра объекта (объекта, для которого вызывается неявная функция-член). Оно может появляться в следующих контекстах:

2) Внутри объявления любой неявной функции-члена объекта в любом месте после (опциональной) cv-квалификаторной последовательности, включая спецификацию исключений и завершающий возвращаемый тип (начиная с C++11) .
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; }
};

Ключевые слова

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 использоваться в
статической функции-члене неассоциированного класса
прояснено