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

相关推荐
江畔柳前堤2 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
Wang's Blog3 小时前
Go-Zero 项目开发47:自研微服务框架的必要性与核心结构设计
开发语言·微服务·golang
白鸽(二般)3 小时前
MinIO Java Client API
java·开发语言
hPw0eKIqD3 小时前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
程序员爱德华4 小时前
Python与C++:异同点对比
c++·python
临床数据科学和人工智能兴趣组4 小时前
要使用 R Markdown,首先需要安装 R 和 RStudio,接着安装 rmarkdown 包
开发语言·数据挖掘·数据分析·r语言·r语言-4.2.1
软萌萌的14 小时前
Java Spring Boot 修改yml配置&加载顺序规则
java·spring boot·python
Nebula嵌入式4 小时前
【C语言】09-深入解析main函数
linux·c语言·开发语言·嵌入式
IT小盘5 小时前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt
爱敲键盘的猴子5 小时前
Java并发编程 -- volatile
java·java并发