【C++】this指针

this指针!

目录

  • this指针的引出:
    • 从C语言中理解this指针:
  • this指针的特性:
  • 练习:

this指针的引出:

我们知道,类中的成员函数是有专门的存放区:公共代码区,这也就意味着我们进行函数调用的时候用的都是一个函数。
既然如此那么我们进行成员函数调用时,编译器是如何知道要操作的对象是什么呢

d1.Print();
d2.Print();

C++中通过引入this指针解决该问题,即:

void Print()
{cout << _year << endl;
} 
// 底层
void Print(Date* this)
{cout << this->_year << endl;
}

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

从C语言中理解this指针:

我们可以将C++中调用成员函数的代码翻译为C语言代码:
例如:我们有如下C++代码

class Car
{
public:int m_price;   // 成员变量void SetPrice(int p) // 成员函数{m_price = p;}
};int main()
{Car car;car.SetPrice(20000); // 给car对象m_price成员变量赋值return 0;
}

如何进行翻译呢?
先来看结果。

struct Car
{int price; 
};void SetPrice(struct Car* this, int p)
{ this->price = p; 
}int main() 
{struct Car car;SetPrice( &car, 20000); // 给car结构体的price变量赋值return 0;
}

接下来解释一下为什么这么翻译

注意

我们只是更形象的类比的理解,不要过分深究,毕竟C语言和C++还是有不同的

我们知道C语言中可没有class关键字,但是有struct关键字
故:

struct Car
{int price; 
};

但是C语言成员函数的概念,更没有所谓的公共代码区,所以我们选择将成员函数类比为全局函数。

void SetPrice(struct Car* this, int p)
{ //从这里的this指针我们就可以看到这种做法我们其实是经常用的//比如栈的压栈啦等等//stackpush(stack* ps, int val);this->price = p; 
}

最后就是main函数中的调用:、

int main() 
{struct Car car;SetPrice( &car, 20000);return 0;
}

这种视角博主是从知乎这看到的,觉得对于this指针的理解比较有用,大家可以读一读原文

this指针的特性:

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

练习:

(1)下面的程序的运行结果是? A.编译报错 B.运行崩溃 C.正常运行

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

答案:C,
按照将程序翻译为C语言的理解:p->Show()类似为Show(nullptr),传递一个空指针是不影响,毕竟我们并不访问

(2)下面的程序的运行结果是? A.编译报错 B.运行崩溃 C.正常运行


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

答案:B,
按照将程序翻译为C语言的理解:p->Show()类似为Show(nullptr),传递一个空指针是不影响,但是我们对其进行解引用操作就有问题了(解引用空指针就像踹开警察的门)

(3)this指针是存在哪里的?

a.栈 b.堆 c.静态区 d.常量区

答案:a
this指针是个形参,形参是在函数的栈桢里,在函数的栈桢里面的变量是属于栈中的。
有时编译器会使用寄存器对其进行优化,this指针会存在寄存器中。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

方案:将vue项目放在SpringMVC中,并用tomcat访问

需要先将项目生成一次war包才能访问项目的webapp文件夹下的资源&#xff0c;否则tomcat的webapp文件夹下面不会生成对应资源文件夹就无法访问。 问题&#xff1a;目录如下&#xff1a; 今天我测试了一下将vue打包后&#xff0c;放入webapp下面访问&#xff0c;却发现vue项目无…

第九节HarmonyOS 常用基础组件13-TimePicker

1、描述 时间选择组件&#xff0c;根据指定参数创建选择器&#xff0c;支持选择小时以及分钟。默认以24小时的时间区间创建滑动选择器。 2、接口 TimePicker(options?: {selected?: Date}) 3、参数 selected - Date - 设置选中项的时间。默认是系统当前的时间。 4、属性…

软件工程学科的本质

软件工程学科的本质是分析与设计&#xff0c;是画图&#xff0c;是进行软件架构设计&#xff0c;进行进行软件项目管理。而非写代码。 分析有结构化分析&#xff0c;面向对象分析法&#xff0c;都用图来描述表达。 设计有结构化设计&#xff0c;面向对象设计法&#xff0c;都…

云计算运维 · 第三阶段 · git

学习b记 第三阶段 三、持续集成 1、git #安装 yum -y install git[rootgit-git ~]# git config –-global user.name "qxl" # 配置git使用用户 [rootgit-git ~]# git config –-global user.email "qxlmail.com" # 配置git使用邮箱 [rootgit-git ~]# g…

面试题 02.07. 链表相交(力扣LeetCode)

文章目录 面试题 02.07. 链表相交题目描述解题思路c代码优化后c代码 面试题 02.07. 链表相交 题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 …

java代码中直接调用存储过程

开启数据库语句批处理 url: jdbc:mysql://192.168.0.xxx:3306/xxx?useSSLfalse&useUnicodetrue&characterEncodingutf-8&zeroDateTimeBehaviorCONVERT_TO_NULL&serverTimezoneUTC&allowMultiQueriestrue 重点&#xff1a; allowMultiQueriestrue mysql…

医疗保健和生命科学组织的远程访问解决方案

医疗保健和生命科学组织的远程访问解决方案——随时随地为医疗保健和生命科学人员提供相关信息 引领生命科学远程工作的IT新高度 生命科学组织一直承受着改进工作流程、降低成本和比以往更快地交付产品的压力。 使用远程访问和集中式 IT 基础架构&#xff0c;企业可以在加快上…

Linux CPU 负载说明

一、背景 工作中我们经常遇到CPU 负载高&#xff0c;CPU负载高意味着什么&#xff1f; CPU的负载是怎么计算的&#xff1f; top指令中的各个指标代表什么含义&#xff1f; 二、CPU 负载计算方法 在系统出现负载问题&#xff0c;通常会使用uptime和top确认负载&#xff0c;这两…

基于C#制作一个连连看小游戏

基于C#制作一个连连看小游戏,实现:难易度选择、关卡选择、倒计时进度条、得分计算、音效播放等功能。 目录 引言游戏规则开发环境准备游戏界面设计游戏逻辑实现图片加载与显示鼠标事件处理游戏优化与扩展添加关卡与难度选择说明</

备战蓝桥杯--数据结构及STL应用(基础)

今天轻松一点&#xff0c;讲一讲stl的基本操作吧&#xff01; 首先&#xff0c;让我们一起创建一个vector容器吧&#xff01; #include<bits/stdc.h> using namespace std; struct cocoack{ int coco,ck; } void solve(){vector<cocoack> x;for(int i0;i<5;i){…

Java链表(2)

&#x1f435;本篇文章将对双向链表进行讲解&#xff0c;模拟实现双向链表的常用方法 一、什么是双向链表 双向链表在指针域上相较于单链表&#xff0c;每一个节点多了一个指向前驱节点的引用prev以及多了指向最后一个节点的引用last&#xff1a; 二、双向链表的模拟实现 首先…

C++不能直接返回数组

文章目录 前言一、缘由二、示例&#xff1a;函数返回后&#xff0c;指针指向无效内存三、解决方案3.1、动态分配数组3.2、使用 std::vector&#xff1a;&#xff08;最为推荐&#xff09;3.3、使用静态数组&#xff1a; 前言 在 C 中&#xff0c;不能直接返回一个数组。因为数组…

STL:list实现

list是和vector类似的顺序型容器&#xff0c;也是是比vector更为复杂的容器。list是双向带头链表&#xff0c;初始有一个不存数据的头节点&#xff0c;并通过节点内指针将后续节点依次连接起来 。 相较于vector&#xff0c;list特点如下&#xff1a; (1)list可以按需申请&…

使用Docker安装Jenkins,并能够在该Jenkins中使用Docker

1. 构建Dockerfile 试错1 参考https://medium.com/manav503/how-to-build-docker-images-inside-a-jenkins-container-d59944102f30 按照文章里所介绍的&#xff0c;实现在Jenkins容器环境中依然能够调用Docker&#xff0c;需要做到以下几步 下载Jenkins镜像将环境中的docke…

CGAL 网格剖分算法

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 CGAL为我们提供了一种网格剖分算法,它与之前的网格平面分割算法有些类似,只不过它输出的是平面与网格的相交线段,CGAL也为我们提供了一种加速策略(AABB树)。 二、实现代码 #include <iostream> #includ…

java面试算法要刷吗?学算法只是为了面试吗?

在Java的世界里&#xff0c;算法往往被看作是面试的一个重要组成部分。有些人可能会问&#xff0c;学Java不是应该更多关注框架、数据库、微服务之类的吗&#xff1f;为什么还要费那么大劲去研究算法呢&#xff1f;好吧&#xff0c;让我来给你讲讲这背后的逻辑。 1、算法在Jav…

ES6 Reflect详解

文章目录 概述静态方法Reflect.get(target, name, receiver)Reflect.set(target, name, value, receiver)Reflect.has(obj, name)Reflect.deleteProperty(obj, name)Reflect.construct(target, args)Reflect.getPrototypeOf(obj)Reflect.setPrototypeOf(obj, newProto)Reflect.…

项目解决方案:高清视频监控联网设计方案

目 录 一、客户需求 二、网络拓扑图 三、方案描述 四、服务器配置 五、方案优势 1. 多级控制 2. 平台可堆叠使用 3. 支持主流接入协议 4. 多种终端显示 5. 视频质量诊断 6. 客户端功能强大 7. 一机一档 一、客户需求 客户现场存在两个网络环境&#xff0c…

自动化测试CSS元素定位

1.1 CSS定位 1.1.1 绝对路径定位 目标 查找第一个文本为“猜猜看”的a标签 实现 CSS表达式 html>body>div>a[.”猜猜看”] python表达式 driver.find_element_by_css_selector(‘html>body>div>a[.”猜猜看”]’) 1.1.2 相对路径定位 目标 查找第…