【C++】类和对象--this指针详解

目录

如果我们问:"同一个类的两个对象,调用同一个成员函数,函数如何区分该操作谁的数据?" C++的答案是**this指针**。本文将从引入动机到底层实现,系统性地剖析这个核心机制。

this指针的引入

考虑一个日期类:

cpp 复制代码
class Date {
public:
    void Init(int year, int month, int day) {
        _year = year; _month = month; _day = day;
    }
    void Print() {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year, _month, _day;
};

int main() {
    Date d1, d2;
    d1.Init(2022, 1, 11);
    d2.Init(2022, 1, 12);
    d1.Print();
    d2.Print();
    return 0;
}

调用d1.Init(...)时,编译器必须在Init内部将_year等变量绑定到d1的数据。这个绑定机制就是:每个非静态成员函数都隐含了一个形参------指向当前对象的指针,编译器将其命名为this

对于上述Print函数,编译器视角的修饰如下:

cpp 复制代码
void Print(Date* const this) {
    cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
}

对象调用成员函数时,编译器自动将对象的地址作为实参传入:

cpp 复制代码
d1.Print();   // 被转换为 Print(&d1);
d2.Print();   // 被转换为 Print(&d2);

this指针的特性

  1. 类型:类类型* const,也就是说,this是一个指针常量,其指向不可更改,不能给它赋值。
  2. 使用范围:仅在非静态成员函数内部有效,静态成员函数没有this指针。
  3. 本质:成员函数的第一个隐含形参。调用时由编译器自动传递,用户代码中不能显式写出这个形参。但函数内部可以显式使用this,比如this->_year(虽然大部分情况省略)。
  4. 存储位置:this作为函数形参,通常存储在栈或通过寄存器(如x86-32的ecx,x86-64的rdi)传递,具体取决于编译器。对象本身并不存储this指针。
  5. const修饰:若成员函数被const修饰(void Print() const),则this类型变为const 类类型* const,表示不能通过该指针修改对象成员。

隐式传递与显式使用示例

cpp 复制代码
class Date {
public:
    Date(int year, int month, int day) {
        _year = year;
        _month = month;
        _day = day;
    }
    // 隐式 this:void Print(Date* const this)
    void Print() {
        // 可显式使用 this
        cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};

需要注意的是,虽然我们可以显式写出this->,但多数风格指南建议在访问成员时省略,除非存在局部变量名与成员变量名冲突的情况(如构造函数中参数与成员同名)。

this指针是C++实现对象模型的核心支柱,它贯穿于所有非静态成员函数的调用。掌握它,才能彻底理解构造函数、析构函数、运算符重载等后续知识。接下来,我们正式进入类的六大默认成员函数之旅。

相关推荐
SL_staff2 小时前
JVS低代码完整源码解析:如何二次开发自己的表单组件?
java·低代码·vuex
ch0sen1pm2 小时前
加班之余从零写了个 spdlog 风格的日志库
c++
JackieZhengChina2 小时前
image-viewer-js 开源图片查看插件完整教程
开发语言·javascript·开源
QN1幻化引擎2 小时前
Gravity-Anchored Cognitive Field Architecture: The DalinX V8/V10 Implementation
java·前端·算法
一生有你20202 小时前
Spring AI ChatMemory 监控与排查:从指标到排错全链路
java·人工智能·spring
吃着火锅x唱着歌2 小时前
Effective C++ 学习笔记 条款33 避免遮掩继承来的名称
c++·笔记·学习
光影少年2 小时前
react的View/Text/Image/ScrollView 常用组件注意事项
开发语言·前端·javascript·react.js·前端框架
程序员黎剑2 小时前
我把算卦变成了一段if-else
java·vue.js·spring boot·后端·ai编程
头茬韭菜2 小时前
4.1-4.2 工具注册 — Fail-Closed 类型安全设计与四层工具架构
java·安全·架构