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

【C++】类和对象·this指针

C++中的类与C语言中的结构体有很多的相似的地方,可以说本质上除了结构体只能定义成员变量,以及结构体默认的访问控制权限是public之外与class没啥区别。但是结构体变量每次调用函数的时候需要指针,而类中的成员函数明明被保存在公共代码段,他们调用的也是同一个函数,对象调用函数却不用传指针也能精准对对象的数据成员进行操作,其实是编译器默默承担了这一切。编译器自动地生成了一个this指针,作为成员函数的一个参数...


一、什么是this指针?

        this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址


二、放入代码中理解

在正常创建类和实例化对象时我们是这样做的:

class date
{
public:date(int year, int month, int day){_year = year;_month = month;_day = day;}void print_d(){cout << _year << "年" << _month << "月" << _day << "日" << endl;;}
private:int _year;int _month;int _day;};int main()
{date d1(2024, 7, 17);date d2(2024, 7, 18);d1.print_d();d2.print_d();return 0;
}

实际上编译器对成员函数和对象调用函数做了以下的改变(粗体的部分):

this指针的相关形参和实参是不能显示着写的(背景为绿色的部分),但是在类里面可以显示着使用(背景为蓝色的部分)

    date(date* const this, int year, int month, int day)
    {
        this->_year = year;
        this->_month = month;
        this->_day = day;
    }
    void print_d(date* const this)
    {
        cout << this->_year << "年" << this->_month << "月" << this->_day << "日" << endl;
    }

    date d1(&d1, 2024, 7, 17);
    date d2(&d2, 2024, 7, 18);

    d1.print_d(&d1);
    d2.print_d(&d2);

以上表达式中 this->_year= year; 和 (*this)._year = year; 以及 _year = year; 是一样的,初期的时候可以在类里将this直接写出来方便自己理解,后期可以直接省略。(此时也能表明类的成员变量要有特定表示比较好,_year和year更直观便捷) 。


三、this指针小知识

  1.this指针存放在哪里?

        指针是形参,存在栈帧上,vs下存到ecx寄存器中。

  2.this指针的类型

        CLASS* const this    (const在*后修饰的是指针,在*前修饰的是指针指向的对象) 这意味着this指针是不能修改的,它不能显示着写,所以也不存在修改一说。

  3.关于this指针的小题目

(下列程序会有怎样的运行结果?)

class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->Print();return 0;
}

 👆这个程序其实是会正常运行的,虽然this指针为空,但是Print()函数并没有使用到this指针,所以也没有出问题。

class A
{
public:void PrintA(){cout << _a << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->PrintA();return 0;
}

 👆而这个程序就会运行崩溃(还是能通过编译的如果出现了p->_a = 1;这种直接空指针访问了对象成员变量会不能编译通过报错),因为this指针被使用了,但它是一个空指针。(当然,每个编译器不一样,在这个问题上也可能会有不同的结果出现随机值,正常运行(编译器优化)都是有可能的)


-The End-

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 科技出海|百分点科技智慧政务解决方案亮相非洲展会
  • HLS加密技术:保障流媒体内容安全的利器
  • WebAssembly与JavaScript的交互(1)
  • Mongodb文本索引
  • react页面指定dom转pdf导出
  • 网络通信介绍
  • css3 中的伪类和伪元素
  • 数学建模-Topsis(优劣解距离法)
  • Node.js实现文件下载
  • 记录些MySQL题集(15)
  • idea Apipost 插件导出接口文档字段类型全部是string
  • webpack和vite
  • (算法)区间调度问题
  • electron 的nsis配置
  • myeclipse开发ssm框架项目图书管理系统 mysql数据库web计算机毕业设计项目
  • 【刷算法】求1+2+3+...+n
  • 11111111
  • Docker入门(二) - Dockerfile
  • ES10 特性的完整指南
  • java多线程
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • linux安装openssl、swoole等扩展的具体步骤
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Rancher如何对接Ceph-RBD块存储
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 前端性能优化——回流与重绘
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 微信开放平台全网发布【失败】的几点排查方法
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (C语言)逆序输出字符串
  • (二十六)Java 数据结构
  • (黑马点评)二、短信登录功能实现
  • (三)模仿学习-Action数据的模仿
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)iOS字体
  • (转)人的集合论——移山之道
  • *算法训练(leetcode)第四十七天 | 并查集理论基础、107. 寻找存在的路径
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net 生成二级域名
  • .net(C#)中String.Format如何使用
  • .NET/C# 使用反射注册事件
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [.net] 如何在mail的加入正文显示图片
  • [1204 寻找子串位置] 解题报告
  • [20160902]rm -rf的惨案.txt
  • [2669]2-2 Time类的定义
  • [AIGC] HashMap的扩容与缩容:动态调整容量以提高性能
  • [AIGC] Redis基础命令集详细介绍
  • [Android View] 可绘制形状 (Shape Xml)
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BZOJ] 1001: [BeiJing2006]狼抓兔子
  • [C#基础]说说lock到底锁谁?