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

目录

语法

this

表达式 this 是一个 纯右值 表达式 ,其值为 隐式对象参数 (即调用隐式对象成员函数时所在的对象)的地址。它可以出现在以下语境中:

1) 在任何 隐式对象成员函数 体内,包括 成员初始化列表 ,以及 lambda表达式主体 (自C++11起)
2) 在任何隐式对象成员函数的 声明 中,位于(可选的)cv限定符序列之后的任意位置,包括 异常规范 以及尾随返回类型 (C++11 起)
4) 在 lambda 表达式的 捕获列表 中。
(C++11 起)

说明

this 只能与其出现位置的最内层封闭类相关联,即使该出现在上下文中是无效的:

class Outer
{
    int a[sizeof(*this)];            // 错误:不在成员函数内部
    unsigned int sz = sizeof(*this); // 正确:位于默认成员初始化器中
    void f()
    {
        int b[sizeof(*this)];     // 正确
        struct Inner
        {
            int c[sizeof(*this)]; // 错误:不在Inner的成员函数内部
                                  // “this”不与Outer关联
                                  // 即使它位于Outer的成员函数内部
        };
    }
};

在类 X 的成员函数中, this 的类型为 X* (指向 X 的指针)。如果成员函数通过 cv 限定符序列 cv 声明,则 this 的类型为 cv X* (指向具有相同 cv 限定的 X 的指针)。由于构造函数和析构函数不能声明 cv 限定符,其中的 this 类型始终为 X* ,即使在构造或销毁 const 对象时也是如此。

在类模板中, this 是一个 依赖表达式 ,显式使用 this - > 可以强制其他表达式成为依赖表达式。

template<typename T>
struct B
{
    int var;
};
template<typename T>
struct D : B<T>
{
    D()
    {
        // var = 1;    // 错误:“var”在此作用域内未声明
        this->var = 1; // 正确
    }
};

对象构造期间 ,如果通过非直接或间接从构造函数的 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 获取 a,d.b 的值现在是未指定的

可以执行 delete this ; ,前提是程序能够保证该对象是通过 new 分配的。然而,这会使所有指向已释放对象的指针失效,包括 this 指针本身:在 delete this ; 返回后,此类成员函数不能引用类的任何成员(因为这涉及对 this 的隐式解引用),且不能再调用其他任何成员函数。

这可用于引用计数指针的成员函数中 (例如 std::shared_ptr (since 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 可能被别名化
此情形下同样
禁止别名化
CWG 2869 C++98 未明确 this 是否可用于
非关联类的静态成员函数
已明确规范