名前空間
変種
操作

this ポインタ

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

[編集] 構文

this

キーワード this は、メンバ関数が呼ばれたオブジェクトのアドレスを値とする prvalue です。 以下の文脈で現れることができます。

1) 任意の非静的メンバ関数の本体内 (メンバ初期化子リストを含みます)。
2) 非静的メンバ関数の宣言内の、 (オプショナルな) cv 修飾列の後の、任意の場所 (動的例外指定(非推奨)noexcept 指定(C++11)、および後置戻り値型(C++11およびそれ以降)を含みます)。
3) デフォルトメンバ初期化子(C++11およびそれ以降)

クラス X のメンバ関数内における this の型は X* (X へのポインタ) です。 メンバ関数が cv 修飾されている場合は、 this の型は cv X* (同じに cv 修飾された X へのポインタ) です。 コンストラクタおよびデストラクタは cv 修飾できないため、それらの中では this の型は常に X* です (たとえ const オブジェクトを構築または破棄するときでも)。

this キーワードが許される何らかの文脈 (非静的メンバ関数の本体、メンバ初期化子リスト、デフォルトメンバ初期化子) で非静的クラスメンバが使用されたときは、その名前の前に暗黙の this-> が自動的に追加され、メンバアクセス式となります (そのメンバが仮想メンバ関数の場合は、仮想関数呼び出しとなります)。

クラステンプレートでは、 this依存式であり、別の式を強制的に依存式とするために明示的な this-> が使用されることがあります。

オブジェクト の構築中に、そのオブジェクトまたはそのいずれかの部分オブジェクトの値が、そのコンストラクタの 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 を通して取得しなかったため、 d.b は未規定です。

オブジェクトが new によって確保されたことをプログラムが保証できる場合は、 delete this; を実行することができますが、これは解放されたオブジェクトへのすべてのポインタ (this ポインタ自身を含みます) を無効にします。 delete this; が戻った後、そのメンバ関数はクラスのメンバを参照することはできず (this の暗黙の逆参照を発生するため)、他のメンバ関数も呼ぶことはできません。 これは、例えば、管理対象オブジェクトへの最後の参照がスコープ外に出るとき、参照カウントをデクリメントする責任を持つ std::shared_ptr の制御ブロックのメンバ関数で、使用されます。

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 は const です。
    }
 
    void foo(int x) // 引数 x が同じ名前のメンバを隠蔽します。
    {
        this->x = x; // 無修飾の x は引数を参照します。
                     // 曖昧性解消のために this-> が必要です。
    }
 
    int y;
    T(int x) : x(x), // メンバ x 初期化するために引数 x を使用します。
               y(this->x) // メンバ y を初期化するためにメンバ x を使用します。
    {}
 
    T& operator= ( const T& b )
    {
        x = b.x;
        return *this; // オーバーロード演算子の多くは *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 のメンバ関数の中ではありません。
        };
    }
}