this 指针
更新时间:2026-08-27。本文是
languages/cpp/主题入门层第 21 篇。每个成员函数里都藏着一个看不见的this——指向当前对象的指针。它是"成员函数凭什么知道该操作哪个对象"的答案,也是链式调用和 const 成员函数绕不开的角色。
本文要回答的问题
this是什么?从哪来?- 返回
*this为什么能链式调用? - const 成员函数里的
this有什么不同?
一、this:指向"当前对象"的隐藏指针
成员函数编译后其实长得像 C 的函数——第一个参数藏着一个对象指针:
class Circle {
double radius_;
public:
void setRadius(double r);
};
// 编译器的视角(等价于):
void Circle_setRadius(Circle* this, double r); // 隐藏参数调用 c.setRadius(5.0) 时,编译器传的是 &c。这个隐藏参数在函数里就叫 this——指向当前对象的指针。所以成员函数里写 radius_,编译器实际当 this->radius_ 用。
每个成员函数里都有 this(静态成员函数除外,下一篇讲),它就是你操作的那个对象的地址。
二、什么时候显式写 this
平时不用写,编译器自动加。需要显式写的场景:
class Circle {
double radius_;
public:
void setRadius(double radius) { // 参数名和成员同名
this->radius_ = radius; // 必须用 this-> 区分成员和参数
}
};参数 radius 把成员 radius_ 的名字占了(同名遮蔽),这时 radius_ 指参数还是成员?C++ 规定:成员函数里裸写 radius_ 优先指参数。所以要显式 this->radius_ 才能拿到成员。很多风格指南要求参数名和成员名刻意不同(成员带 _ 后缀就是这个原因),能少写很多 this->。
三、返回 *this:链式调用的秘密
this 是地址,*this 就是对象本身。成员函数返回 *this(的引用),调用就能串起来:
class Logger {
int level_;
public:
Logger& setLevel(int l) {
level_ = l;
return *this; // 返回自己
}
Logger& setPrefix(const std::string& p) {
prefix_ = p;
return *this;
}
};
Logger log;
log.setLevel(2).setPrefix("[app]"); // 链式:一个一个接着调setLevel 返回 *this(Logger&),所以 .setLevel(2) 的结果还是那个 log,可以继续 .setPrefix(...)。iostream 的 std::cout << a << b 能连续写、std::string 的 s.append(...).append(...) 能连环调,背后都是这个套路。
注意返回类型:要返回 Logger&(引用),返回 Logger(值拷贝)会复制一份,链式调用就操作副本了。
四、const 成员函数:this 变成了 const 指针
class Circle {
double radius_;
public:
double area() const { // const 成员函数
return 3.14159 * radius_ * radius_;
}
};const 出现在函数名后面,表示"这个成员函数不修改对象"。此时函数里的 this 类型是 const Circle*——通过它只能读、不能写。试试写 radius_ = 1;,编译报错。
两个作用:
- 自证清白:告诉调用方"调用我保证不改对象",这是接口契约;
- 才能被 const 对象调用:
const Circle c; c.area();只有 const 成员函数能调(非 const 成员函数会尝试修改,编译拒绝)。
前面文章里 area() const 的 const 一直出现,现在补上了这最后一环。
五、和 C 对比
| 对比项 | C | C++ |
|---|---|---|
| 操作哪个对象 | 手动传 struct* p | 自动传隐藏 this |
| 语法 | p->radius | this->radius_(可省略) |
| 链式调用 | 手动返回指针 | 返回 *this |
| const 保护 | 无(const 传参能缓解) | const 成员函数编译期强制 |
| 静态场景 | 全局函数 | 静态成员函数(无 this) |
C 里做"面向对象"全是手动活:area(&c)、setRadius(&c, 5),对象指针在参数列表里进进出出。C++ 把 this 藏起来自动传,代码读起来像"对象自己的行为",写起来少一半参数。
六、与本站主线衔接
- 静态成员函数没有
this(不绑定到具体对象),见 静态成员; - const 成员函数与 const 对象的重载,见 const 成员函数;
this的实现细节(寄存器传对象地址)与调用约定,见专家层对象内存布局。
一句话总结
this 是成员函数里指向当前对象的隐藏指针(底层就是编译器的第一个参数),同名遮蔽时用 this-> 区分,返回 *this 实现链式调用;const 成员函数里 this 变成 const T*,只能读不能写,也因此才能被 const 对象调用;静态成员函数没有 this。