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

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - その他のテキスト(Syntax、Explanation、Keywords、Example、Defect reports)はC++関連の専門用語として翻訳せず、原文のまま保持しました - HTMLタグ、属性、 内の数字はすべて変更せず保持しました - 書式設定と構造は完全に維持されています

構文

this

this は、 prvalue expression であり、その値は implicit object parameter (暗黙のオブジェクトメンバー関数が呼び出されているオブジェクト)のアドレスです。以下の文脈で使用できます:

1) 任意の 暗黙的なオブジェクトメンバー関数 の本体内部で、これには メンバー初期化子リスト および ラムダ式本体 (C++11以降) が含まれます。
2) 任意の暗黙的なオブジェクトメンバー関数の宣言内で、CV修飾子シーケンス(任意)以降のどこでも、以下のものを含む: declaration exception specification およびトレーリングリターン型 (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のメンバー関数内であっても
        };
    }
};

X クラスのメンバ関数における this の型は X* (Xへのポインタ)です。メンバ関数が CV修飾子シーケンス付きで宣言されている場合 cv this の型は cv X* (同一のCV修飾がされたXへのポインタ)となります。コンストラクタとデストラクタはCV修飾子で宣言できないため、それらにおける this の型は、constオブジェクトを構築または破棄する場合でも常に 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
    }
};

オブジェクトの構築中 に、オブジェクトまたはその部分オブジェクトの値が、コンストラクタの this ポインタから直接的または間接的に取得されていないglvalueを通じてアクセスされた場合、そのようにして取得されたオブジェクトまたは部分オブジェクトの値は未規定です。言い換えれば、コンストラクタ内では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 経由で a を取得していないため、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 nested class内で this が使用された場合、
それがnested classとassociatedするか
enclosing classとassociatedするかが未規定
this は常に最も内側の
nested classとassociatedし、
非staticメンバ関数内かどうか
に関わらない
CWG 2271 C++98 非constオブジェクトの構築時に
this がエイリアス化される可能性があった
この場合もエイリアス化は
禁止される
CWG 2869 C++98 非associatedクラスのstaticメンバ関数内で
this が使用可能か不明確だった
明確化された