Spec-Zone.ru › C++

Указатель this

Синтаксис

this

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

1) В теле любой функции-члена с неявным объектом, включая список инициализации членов и тело лямбда-выражения(начиная с C++11).
2) В объявлении любой функции-члена с неявным объектом после последовательности cv-квалификаторов (если она есть), в том числе в спецификации исключений и завершающем типе возвращаемого значения(начиная с 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-квалификаторов cv, тип this — это cv X* (указатель на X с теми же cv-квалификаторами). Поскольку конструкторы и деструкторы нельзя объявлять с cv-квалификаторами, тип this в них всегда X*, даже при создании или уничтожении константного объекта.

В шаблонах классов 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; }
};

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

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->” is 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 можно было псевдонимизировать при
конструировании неконстантного объекта
псевдонимизация также
запрещена в этом случае
CWG 2869 C++98 было неясно, можно ли использовать this в
статической функции-члене несвязанного класса
прояснено

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/this

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API