The
this
pointer
目次 |
構文
this
|
|||||||||
式 this は、 prvalue expression であり、その値は implicit object parameter (暗黙のオブジェクトメンバー関数が呼び出されているオブジェクト)のアドレスです。以下の文脈で使用できます:
|
3)
デフォルトメンバ初期化子
内。
4)
ラムダ式のキャプチャリスト
内。
|
(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; } };
キーワード
例
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 が使用可能か不明確だった |
明確化された |