C++this指针

我们由一个题目引入:

class Date
{
public:
    void Init(int year=2024, int month=1, int day=27)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1, d2;
    d1.Init();
    d1.Print();
    d2.Init(2023, 10, 24);
    d2.Print();
    return 0;
}

面对如上代码,我想问Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏
的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”
的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编
译器自动完成

 

一.this指针的特性

void Print(Date* const this)
{
    cout << this->_year << "-" <<this-> _month << "-" << this->_day << endl;
}
void Print()
{
    cout << _year << "-" << _month << "-" << _day << endl;
}
//两者等价

此时我们就发现了this指针的特性:

1. this指针的类型:类型* const,即成员函数中,不能给this指针赋值。
2. 只能在“成员函数”的内部使用
3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
this形参。所以对象中不存储this指针。
4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传
递,不需要用户传递

注意点:

1.this指针存在于形参和实参的位置,我们是不可以认为显示的写

2.函数内部可以使用

现在大家简单能理解了this指针,现在我们以问答的方式来深入理解this指针:

1.this 存在哪里 b 因为他是一个形参?(不算放在寄存器的)

 a、堆 b、栈 c、静态区 d、常量区 e、对象里面

答案是;b

解析;

首先最不能选的是e,如果this指针放对象里面,它是不是一个指针,那么肯定要占用4/8字节的空间 但是计算的时候我们是不是没有计算this指针的大小,所以排除e

a是动态开辟的空间存放的位置,c静态区是存放全局变量或static修饰的内容,所以这两个也可以排除

对于常量区我们听名字就知道常量区是指在程序运行是不发生改变的量,this指针的对象是没有被const修饰,所以可以改变,而const修饰了this指向,所以this不能改变指向,但是可以改变指向的内容,所以不存在常量区。
综上,this指针在栈区,选b。

问题2:

下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

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

结果:

所以答案选:C

解析:

我们定义了一个A类指针指向nullptr,然后执行ptr->print(),隐式传递了this指针,但是是空指针,而在我们的成员函数内部并没有涉及到this指针方面内容,所以可以正常调用,这里我们可以检查this指针是不是空:

问题三:

下面程序编译运行结果是?

A、编译报错B、运行崩溃 C、正常运行

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

结果发现什么都没输出,可见程序崩了。

答案选:B

补充:(我们没有任何错误,就不可能是在编译时错误,排除A)

解析:

这题和上题区别在于我们我们成员函数与this指针息息相关了,但是该指针是指向空,所以我们我们根本访问不到类的成员变量,所以程序崩了,所以选B

问题四:

下面程序编译运行结果是?

A、编译报错B、运行崩溃 C、正常运行

class A
{
public:
    void print()
    {
        cout << "print()" << endl;
    }
private:
    int _a;
};
int main()
{
    A* ptr = nullptr;
    (*ptr).print();
    return 0;
}

选C

这题我们将前面的放在一起来分析:

我重写一段代码:

class A
{
public:
    void print()
    {
        cout << this << endl;
        cout << _a << endl;
        cout << "print()" << endl;
    }
private:
    int _a=10;
};
int main()
{
    A* ptr = nullptr;
    (*ptr).print();
    return 0;
}

我们发现结果是第三个cout失败导致程序崩了,所以我们的调用:(*ptr).print()理解尤为重要,这里我们可以理解为:虽然我们对ptr指针解引用了,但是我们实际问题和问题三一样。

最后,感谢大家的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/353989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云推出第八代企业级实例 g8i:AI 推理性能最高提升 7 倍、可支持 72B 大语言模型

云布道师 1 月 11 日&#xff0c;全球领先的云计算厂商阿里云宣布推出第八代企业级通用计算实例 ECS g8i&#xff0c;这也是国内首款搭载第五代英特尔至强可扩展处理器&#xff08;代号 EMR&#xff09;的云计算产品。依托阿里云自研的「飞天CIPU」架构体系&#xff0c;ECS g8…

分布式事务入门,最终一致性方案

分布式事务 回顾分布式事务 上篇内容我们说到了分布式事务的基本内容&#xff0c;讲到了分布式事务的实现主要有事务协调以及最终一致性两件事情来完成整个逻辑。 那么上个文章我们说过了 2PC、3PC、XA 三种协调事务的协议&#xff0c;这次我们来说事务协调处理完成后&#x…

node.js 分布式锁看这篇就够用了

Redis SETNX 命令背后的原理探究 当然&#xff0c;让我们通过一个简单的例子&#xff0c;使用 Redis CLI&#xff08;命令行界面&#xff09;来模拟获取锁和释放锁的过程。 在此示例中 获取锁: # 首先&#xff0c;设置锁密钥的唯一值和过期时间(秒) 127.0.0.1:6379> SET …

小型商用机器人,如何做到小而强?

兼顾体型和性能。 体型和性能的矛盾 一直以来&#xff0c;商用清洁机器人的应用场景主要集中在大型商场、超市、写字楼等&#xff0c;为什么1000平米以下的小型商超等中小场景却很少涉足&#xff1f;原因可以说有很多&#xff0c;但核心为两方面&#xff0c;一方面&#xff0…

2024幻兽帕鲁服务器,阿里云配置

阿里云幻兽帕鲁服务器Palworld服务器推荐4核16G配置&#xff0c;可以选择通用型g7实例或通用算力型u1实例&#xff0c;ECS通用型g7实例4核16G配置价格是502.32元一个月&#xff0c;算力型u1实例4核16G是432.0元/月&#xff0c;经济型e实例是共享型云服务器&#xff0c;价格是32…

Metaphor(EXA) 基于大语言模型的搜索引擎

文章目录 关于 Metaphor使用示例 关于 Metaphor Metaphor是基于大语言模型的搜索引擎&#xff0c;允许用户使用完整的句子和自然语言搜索&#xff0c;还可以模拟人们在互联网上分享和谈论链接的方式进行查询内容。 Metaphor同时还能与LLMs结合使用&#xff0c;允许LLMs连接互联…

网络安全04-sql注入靶场第一关

目录 一、环境准备 1.1我们进入第一关也如图&#xff1a; ​编辑 二、正式开始第一关讲述 2.1很明显它让我们在标签上输入一个ID&#xff0c;那我们就输入在链接后面加?id1 ​编辑 2.2链接后面加个单引号()查看返回的内容&#xff0c;127.0.0.1/sqli/less-1/?id1,id1 …

粒子群优化算法(Particle Swarm Optimization,PSO)求解基于移动边缘计算的任务卸载与资源调度优化(提供MATLAB代码)

一、优化模型介绍 移动边缘计算的任务卸载与资源调度优化原理是通过利用配备计算资源的移动无人机来为本地资源有限的移动用户提供计算卸载机会&#xff0c;以减轻用户设备的计算负担并提高计算性能。具体原理如下&#xff1a; 任务卸载&#xff1a;移动边缘计算系统将用户的计…

网站防护可以采用高防SCDN吗?

随着网络攻击日益复杂和频繁&#xff0c;网站安全已经成为业界的头等大事。在这个背景下&#xff0c;高防SCDN&#xff08;高防御内容分发网络&#xff09;作为一种强大的网络保护工具&#xff0c;正逐渐成为各类网站不可或缺的安全设施。很多人会问&#xff0c;网站防护可以采…

项目解决方案:4G/5G看交通数字化视频服务平台技术方案

目 录 1.总体描述 2.系统结构图 3.系统功能 3.1 信息交互 3.2 语音对讲 3.3 实时码流转换 3.4 流媒体集群和扩容 3.5 负载均衡 3.6 流媒体分发 3.7 流媒体点播 4.系统标准 4.1 流媒体传输 4.2 视频格式 4.3 质量标准 5.设备清单 1.总体描述 视频监控平…

【学术论文写作 笔记02】 鲁棒性实验写作的行文逻辑

文章目录 一、声明二、行文思路三、示例范文一范文二 一、声明 自己总结的&#xff0c;有问题望指正&#xff01; 二、行文思路 为什么要做鲁棒性测试怎么做实验结论对结果的解释 三、示例 PPT 范文一 2022, TIM, “A Robust and Reliable Point Cloud Recognition Netw…

跟着cherno手搓游戏引擎【13】着色器(shader)

创建着色器类&#xff1a; shader.h:初始化、绑定和解绑方法&#xff1a; #pragma once #include <string> namespace YOTO {class Shader {public:Shader(const std::string& vertexSrc, const std::string& fragmentSrc);~Shader();void Bind()const;void Un…

Adobe ColdFusion 任意文件读取漏洞复现(CVE-2023-26361)

0x01 产品简介 Adobe ColdFusion是美国奥多比(Adobe)公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion平台 filemanager.cfc接口存在任意文件读取漏洞,攻击者可通过该漏洞读取系统重要文件(如数据库配置文件、系统配…

56. 合并区间 - 力扣(LeetCode)

题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 题目示例 输入&#xff1a;intervals [[1,3…

专有钉钉开发记录,及问题总结

先放几个专有钉钉开发文档 专有钉钉官网的开发指南 服务端(后端)api文档 前端api文档 前端开发工具下载地址 小程序配置文件下载地址 后端SDK包下载地址 专有钉钉域名是openplatform.dg-work.cn 开发记录 开发专有钉钉时有时会遇到要使用钉钉的api&#xff1b;通过 my 的方…

分布式id-雪花算法

一、雪花算法介绍 Snowflake&#xff0c;雪花算法是有Twitter开源的分布式ID生成算法&#xff0c;以划分命名空间的方式将64bit位分割成了多个部分&#xff0c;每个部分都有具体的不同含义&#xff0c;在Java中64Bit位的整数是Long类型&#xff0c;所以在Java中Snowflake算法生…

台式电脑的ip地址在哪里找

在网络连接方面&#xff0c;IP地址是非常重要的信息&#xff0c;它是用于标识网络设备的唯一地址。对于台式电脑用户来说&#xff0c;了解自己设备的IP地址是非常有必要的&#xff0c;因为它可以帮助解决网络连接问题&#xff0c;进行远程访问和共享文件等功能。本文将指导读者…

spring整合mybatis的底层原理

spring整合mybatis的底层原理 原理&#xff1a; FactoryBean的自定义对象jdk动态代理Mapper接口对象 一、手写一个spring集成mybatis 目录结构&#xff1a; 1.1 入口类 public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext co…

使用一个定时器(timer_fd)管理多个定时事件

使用一个定时器(timer_fd)管理多个定时事件 使用 timerfd_xxx 系列函数可以很方便的与 select、poll、epoll 等IO复用函数相结合&#xff0c;实现基于事件的定时器功能。大体上有两种实现思路&#xff1a; 为每个定时事件创建一个 timer_fd&#xff0c;绑定对应的定时回调函数…

7-205 神奇的循环

通过自己双手写出来的代码真的很有成就感 我们知道&#xff0c;在编程中&#xff0c;我们时常需要考虑到时间复杂度&#xff0c;特别是对于循环的部分。例如&#xff0c; 如果代码中出现 for(i1;i<n;i) OP ; 那么做了n次OP运算&#xff0c;如果代码中出现 for(i1;i<n; i)…