X Tutup
The Wayback Machine - https://web.archive.org/web/20240623073106/https://ru.cppreference.com/w/cpp/language/this
Пространства имён
Варианты
Действия

Указатель this

Материал из cppreference.com
< cpp‎ | language
 
 
 
 

Содержание

[править] Синтаксис

this

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

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

В шаблонах классов 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) не получено через 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++:

Номер Применён Поведение в стандарте Корректное поведение
CWG 760 C++98 когда this используется во вложенном классе, не указано,
связан ли он с вложенным классом или окружающим
классом
this всегда ассоциируется с самым внутренним
вложенным классом, независимо от того,
находится ли он в нестатической функции-элементе
CWG 2271 C++98 this мог быть псевдонимом при создании неконстантного
объекта
псевдоним также запрещён в этом случае
X Tutup