The
this
pointer
目录 |
语法
this
|
|||||||||
表达式 this 是一个 纯右值 表达式 ,其值为 隐式对象参数 (即调用隐式对象成员函数时所在的对象)的地址。它可以出现在以下语境中:
|
3)
在
默认成员初始化器
中。
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; } };
关键词
示例
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
是否可用于
非关联类的静态成员函数 |
已明确规范 |