当前位置: 首页 > article >正文

【C++】隐含的“This指针“

目录

一、问题引入

二、定义

三、this 指针的特性

一、问题引入

我之前有一处疑惑,如果在成员函数中调用其他成员函数,如果不使用对象名作为前缀怎么判断的是要对哪个对象进行操作呢(虽然大概率是当前对象)?原来,成函数调用时会有一个隐藏的指针变量也就是this指针,它指向当前对象的位置,在调用该对象的成员函数时,其中的调用的其他的成员函数之前会自动加上这个指针,也就代表着当前对象的调用,如下:

#include <iostream>
//这是一个简单的日期类
class Date {
private:
    int day;
    int month;
    int year;

public:
    // 初始化方法
    void Init(int d, int m, int y) {
        day = d;
        month = m;
        year = y;
    }
    // 打印日期方法
    void Print() const {
        std::cout << day << "-"
                  << month << "-"
                  << year << std::endl;
    }

    // 自定义方法
    void test(){
        Print();//注意这里,我们可以直接使用Print()
                //而不是像main函数一样在调用时需要再前声明类域
    }

};

等价于以下操作: 

void test()
{
     this->Print();   
}

二、定义

C++中的this指针是一个指向当前对象指针。在类的成员函数中,可以使用this指针来访问当前对象的成员变量和成员函数。this指针的使用可以简化代码,提高代码的可读性和可维护性,这点如果你学过Python的话可以类比Python中的self指针的调用,Python中的调用是显式的,C++中是隐藏起来的。但是实际中,调用函数会自动携带它,会隐藏起来,但是仍能够使用,比如

void setAge(int a) {
    this->age = a; // 使用this指针访问age成员变量
}

同样的,直接调用age也是可以的,不必须写入。

我们可以通过以下代码验证this指针实质是一个指向对象首地址的指针

//在类中添加以下函数
void VerifyThisPointer() const 
{
    std::cout << "this指针的地址: " << this << std::endl;
}


//在main函数中调用
mian(void)
{
    Date date(13, 11, 2024);
 
    // 获取对象的地址
    Date* datePtr = &date;
 
    // 打印对象的地址
    std::cout << "对象date的首地址: " << datePtr << std::endl;
 
    // 调用 VerifyThisPointer 方法来打印 this 指针的值
    date.VerifyThisPointer();
}

三、this 指针的特性

1. this指针的类型:"类"类型 * const  (对应类的const指针型) ,即成员函数中,不能给this指针赋值

2. 只能在“成员函数”的内部使用。

3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。可以通过观察汇编部分看出。而且就算是对象是一个空,也同样可以调用一部分成员函数。例如:

5.this在实参和形参位置不能显式得写出来,但是可以在类里面显式地用。如下:

#include <iostream>
//这是一个简单的日期类
class Date {
private:
    int day;
    int month;
    int year;

public:
    // 初始化方法
    void Init(int d, int m, int y) {
        this->day = d;
        this->month = m;
        this->year = y;
    }
    // 打印日期方法
    void Print() const {
        std::cout << this->day << "-"
                  << this->month << "-"
                  << this->year << std::endl;
    }

    // 自定义方法
    void test(){
        this->Print();
    }

};

 但是不可以这样使用:这样编译器会报错

    void Init(Data* this, int d, int m, int y) {
        this->day = d;
        this->month = m;
        this->year = y;
    }

6.this指针不占用空间。前面我们已经知道this指针本质是对象的首地址,这个传递操作还是由编译器操作,它没有在对象内部,所以它不占用空间。

7.静态的成员函数没办法操作this指针。因为静态函数先于对象存在,例如即使没有对象的生成你也可以直接调用一部分静态函数。

第四点和第七点可以运行观察以下代码现象:

class Myclass
{
public:
    static void staticPrint()//static修饰的静态成员函数
    {
        std::cout << "staticPrint()" << std::endl;
    }
    void Print()//非静态成员函数
    {
        std::cout << "Print()" << std::endl;
    }

private:
    int a;
};



int main(void)

{
    Myclass::staticPrint();  //这样调用成功
    Myclass::Print();        //这样会报错

    Myclass* p = nullptr;
    p->staticPrint();  //这样可以调用成功
    p->Print();        //这样可以调用成功    
    return 0;
}


http://www.kler.cn/a/395275.html

相关文章:

  • 在 Oracle Linux 8.9 上安装Oracle Database 23ai 23.5
  • 2、 家庭网络发展现状
  • Python 编程入门指南(一)
  • MaxKB
  • react + ts定义接口类型写法
  • 【C#设计模式(4)——构建者模式(Builder Pattern)】
  • GIT将源码推送新分支
  • 第十四章 Spring之假如让你来写AOP——雏形篇
  • 二分查找--快速地将搜索空间减半
  • 大语言模型在序列推荐中的应用
  • MinIo在Ubantu和Java中的整合
  • 某军工变压器企业:通过集团级工业IOT平台,实现数字化转型
  • yakit远程连接(引擎部署在vps上)
  • PyAEDT:Ansys Electronics Desktop API 简介
  • Apache Doris:快速入门与实践
  • word转markdown的方法(pandoc)
  • 2024 年 10 月公链行业研报:比特币引领市场,Layer 2 竞争加剧
  • 如何在Mac上切换到JDK 17开发环境
  • windows C#-创建记录类型(上)
  • 高性能分布式缓存Redis-分布式锁与布隆过滤器
  • Python →爬虫实践
  • 如何在CentOS 7上搭建SMB服务
  • AviEar:一种基于物联网的低功耗鸟类声学监测解决方案
  • SQL HAVING子句
  • 【编码】【特征选择】【降维】
  • 大模型基础BERT——Transformers的双向编码器表示