C++从入门到起飞之——this指针 全方位剖析!

 

                                                                                个人主页:秋风起,再归来~

                                                                                           C++从入门到起飞                         

                                                                       个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!

目录

1、this指针

2、C++和C语⾔实现Stack对⽐

C实现Stack代码

C++实现Stack代码

3.完结散花


1、this指针

class Data
{
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;int _month;int _day;
};

• Date类中有Init与Print两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了 ⼀个隐含的this指针解决这⾥的问题

• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针。⽐如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)

• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this- >_year = year;

class Data
{
public:void Init(int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}void Print(){cout << this->_year << "/" << this->_month << "/" << this->_day << endl;}private://这里只是声明,并没有开空间int _year;int _month;int _day;
};

• C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显 ⽰使⽤this指针。

1.下⾯程序编译运⾏结果是()

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

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

 答案是正常运行原因就在于我们对类类型进行操作(p->Print)时并不是对指针本身进行解引用操作,而是通过传参调用Print函数,我们只是传了空指针,并没有对空指针进行任何访问,所以程序不会报错。

2.下⾯程序编译运⾏结果是()

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

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

我们看到程序并没有正常结束,所以答案是运行崩溃,原因在于函数调用时没有问题,但我们在函数执行期间对空指针进行了解引用(非法访问)

 而对于空指针的访问只有在运行时才会发生,而编译器在编译阶段时不会发现的,所以不是编译错误,而是运行时崩溃。

3.this指针存在内存哪个区域的()

A. 栈  B.堆  C.静态区  D.常量区  E.对象⾥⾯

答案是A!

在C++中,`this` 指针是一个隐含的指向当前对象的指针,它不是由程序员分配的,而是编译器自动创建并插入到每个成员函数的隐式参数列表中的。`this` 指针位于函数调用帧(call stack frame)的局部变量区,通常称为栈空间(Stack),用于存储函数执行时需要的临时数据和指向自身对象的数据。

当函数被调用时,`this` 指针会被初始化为指向调用它的对象实例,这对于访问类的私有成员变量特别有用。记住,`this` 永远不会为空,除非是在静态成员函数或者非成员函数中,这时没有特定的对象关联。

2、C++和C语⾔实现Stack对⽐

⾯向对象三⼤特性:封装、继承、多态,下⾯的对⽐我们可以初步了解⼀下封装。

通过下⾯两份代码对⽐,我们发现C++实现Stack形态上还是发⽣了挺多的变化,底层和逻辑上没啥变 化。 

C实现Stack代码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 满了, 扩容if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity *sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}
STDataType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{assert(ps);return ps->top;
}
int main()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);while (!STEmpty(&s)){printf("%d\n", STTop(&s));STPop(&s);}STDestroy(&s);return 0;
}

C++实现Stack代码

#include<iostream>
using namespace std;
typedef int STDataType;
class Stack
{
public:// 成员函数void Init(int n = 4){_a = (STDataType*)malloc(sizeof(STDataType) * n);if (nullptr == _a){perror("malloc申请空间失败");return;}_capacity = n;_top = 0;}void Push(STDataType x){if (_top == _capacity){int newcapacity = _capacity * 2;STDataType* tmp = (STDataType*)realloc(_a, newcapacity *sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}_a = tmp;_capacity = newcapacity;}_a[_top++] = x;}void Pop(){assert(_top > 0);--_top;}bool Empty(){return _top == 0;}int Top(){assert(_top > 0);return _a[_top - 1];}void Destroy(){free(_a);_a = nullptr;_top = _capacity = 0;}
private:// 成员变量STDataType* _a;size_t _capacity;size_t _top;
};
int main()
{Stack s;s.Init();s.Push(1);s.Push(2);s.Push(3);s.Push(4);while (!s.Empty()){printf("%d\n", s.Top());s.Pop();}s.Destroy();return 0;
}

• C++中数据和函数都放到了类⾥⾯,通过访问限定符进⾏了限制,不能再随意通过对象直接修改数 据,这是C++封装的⼀种体现,这个是最重要的变化。这⾥的封装的本质是⼀种更严格规范的管 理,避免出现乱访问修改的问题。当然封装不仅仅是这样的,我们后⾯还需要不断的去学习。

• C++中有⼀些相对⽅便的语法,⽐如Init给的缺省参数会⽅便很多,成员函数每次不需要传对象地 址,因为this指针隐含的传递了,⽅便了很多,使⽤类型不再需要typedef⽤类名就很⽅便

• 在我们这个C++⼊⻔阶段实现的Stack看起来变了很多,但是实质上变化不⼤。等着我们后⾯看STL 中的⽤适配器实现的Stack,⼤家再感受C++的魅⼒。

3.完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

排序系列 之 快速排序

&#xff01;&#xff01;&#xff01;排序仅针对于数组哦本次排序是按照升序来的哦代码后边有图解哦 介绍 快速排序英文名为Quick Sort 基本思路 快速排序采用的是分治思想&#xff0c;即在一个无序的序列中选取一个任意的基准元素base&#xff0c;利用base将待排序的序列分…

Spring纯注解开发

前言 Spring3.0引入了纯注解开发的模式&#xff0c;框架的诞生是为了简化开发&#xff0c;那注解开发就是简化再简化。Spring的特性在整合MyBatis方面体现的淋漓尽致哦 一.注解开发 以前跟老韩学习SE时他就说&#xff1a;注解本质是一个继承了Annotation 的特殊接口,其具体实…

Unity免费领7月开发者周冰雪世界着色器环境包180种冰材质544种预制变体冰天雪地环境效果限时免费领取20240719

7月19号的Unity开发者周限时免费资产更新啦&#xff0c;这次是冰雪材质和环境素材包&#xff0c;质量挺不错。 之前进过捆绑包&#xff0c; 结帐时输入NATUREMANUFACTURE2024优惠券代码即可免费获得。无需购买。 Unity免费领7月开发者周冰雪世界着色器环境包180种冰材质544种…

DevExpress WinForms自动表单布局,创建高度可定制用户体验(一)

使用DevExpress WinForms的表单布局组件可以创建高度可定制的应用程序用户体验&#xff0c;从自动安排UI控件到按比例调整大小&#xff0c;DevExpress布局和数据布局控件都可以让您消除与基于像素表单设计相关的麻烦。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&a…

系统架构设计师教程 第3章 信息系统基础知识-3.7 企业资源规划(ERP)-解读

系统架构设计师教程 第3章 信息系统基础知识-3.7 企业资源规划&#xff08;ERP&#xff09; 3.7.1 企业资源规划的概念3.7.2 企业资源规划的结构3.7.2.1 生产预测3.7.2.2 销售管理&#xff08;计划&#xff09;3.7.2.3 经营计划&#xff08;生产计划大纲&#xff09;3.7.2.4 …

【人工智能大模型】文心一言介绍以及基本使用指令

目录 一、产品背景与技术基础 二、主要功能与特点 基本用法 指令的使用 注意事项 文心一言&#xff08;ERNIE Bot&#xff09;是百度基于其文心大模型技术推出的生成式AI产品。以下是对文心一言的详细介绍&#xff1a; 一、产品背景与技术基础 技术背景&#xff1a;百度…

初学Linux之常见指令(上)

初学Linux之常见指令&#xff08;上&#xff09; 文章目录 初学Linux之常见指令&#xff08;上&#xff09;1. Linux下的小技巧热键man 指令 2. ls 指令3. pwd 指令4. cd 指令5. tree 指令6. touch 指令7. mkdir 指令8. rmdir 和 rm 指令9. cp 指令10. mv 指令 1. Linux下的小技…

PolarisMesh源码系列--Polaris-Go注册发现流程

导语 北极星是腾讯开源的一款服务治理平台&#xff0c;用来解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题。在分布式和微服务架构的治理领域&#xff0c;目前国内比较流行的还包括 Spring Cloud&#xff0c;Apache Dubbo 等。在 Kubernete…

英文名字网/英文取名/英语起名网源码/带文章系统带采集PHP网站程序

英文名字网/英文取名/英语起名网源码/带文章系统带采集PHP网站程序 演示站&#xff1a; https://enname.wengu8.com/ 程序截图&#xff1a; 程序说明&#xff1a; 1、前端模板PC手机端自适应。 2、全部数据带25W名字数据&#xff0c;后台可编辑&#xff0c;包括json格式的…

【Docker】Docker-compose 单机容器集群编排工具

目录 一.Docker-compose 概述 1.容器编排管理与传统的容器管理的区别 2.docker-compose 作用 3.docker-compose 本质 4.docker-compose 的三大概念 二.YML文件格式及编写注意事项 1.yml文件是什么 2.yml问价使用注意事项 3.yml文件的基本数据结构 三.Docker-compose …

零基础入门鸿蒙开发 HarmonyOS NEXT星河版开发学习

今天开始带大家零基础入门鸿蒙开发&#xff0c;也就是你没有任何编程基础的情况下就可以跟着石头哥零基础学习鸿蒙开发。 目录 一&#xff0c;为什么要学习鸿蒙 1-1&#xff0c;鸿蒙介绍 1-2&#xff0c;为什么要学习鸿蒙 1-3&#xff0c;鸿蒙各个版本介绍 1-4&#xff0…

【用栈操作构建数组】python刷题记录

润到栈模块. class Solution:def buildArray(self, target: List[int], n: int) -> List[str]:#每一个缺失的数字填入pushpop&#xff0c;其他数字只需要填入push即可#再简化思路&#xff0c;读取到的数小于当前&#xff0c;pushpop,直到等于当前才pushans[]cur0for i in ta…

在VS Code上搭建Vue项目教程(Vue-cli 脚手架)

1.前期环境准备 搭建Vue项目使用的是Vue-cli 脚手架。前期环境需要准备Node.js环境&#xff0c;就像Java开发要依赖JDK环境一样。 1.1 Node.js环境配置 1&#xff09;具体安装步骤操作即可&#xff1a; npm 安装教程_如何安装npm-CSDN博客文章浏览阅读836次。本文主要在Win…

zabbix“专家坐诊”第246期问答

问题一 Q&#xff1a;有哪位大哥知道这是啥情况&#xff0c;6.4主动检查接口显示未知&#xff1f; A&#xff1a;看看agent配置文件的主采集有没有填写正确IP。 Q&#xff1a;我刚刚客户端重新授权&#xff0c;发现可以预警了&#xff0c;但是还是灰色的&#xff0c;我尝试输…

直播平台优化方案:直播美颜SDK开发详解

本篇文章&#xff0c;笔者将详细介绍直播美颜SDK的开发过程&#xff0c;帮助开发者为其平台增添这一重要功能。 一、美颜SDK的基本概念 通过美颜SDK&#xff0c;用户在进行直播时可以轻松地美化自己的形象&#xff0c;提高观众的观看体验。 二、美颜SDK的核心功能 1.实时美颜…

人工智能算法工程师(高级)课程2-多类目标识别之RCNN系列模型与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(高级)课程2-多类目标识别之RCNN系列模型与代码详解。本文全面解析了RCNN系列模型&#xff0c;包括R-CNN、Fast R-CNN、Faster R-CNN等&#xff0c;重点阐述了基于PyTorch框架实现多目标检测与识…

成为一位优秀的项目经理,这一点很重要

在管理工作中&#xff0c;我们可能会遇到这样的情况&#xff1a;有的人业务能力很强&#xff0c;堪称行业内的佼佼者&#xff0c;但当领导却仿佛失去了方向&#xff0c;管理起来显得力不从心&#xff0c;甚至一团糟。 业务能力和领导力是两个既相关又独立的概念。 业务能力是…

飞凌嵌入式RK3576开发板的MIPI-CSI调试——通路解析

MIPI-CSI是一种在嵌入式系统或移动设备中常见的摄像头接口&#xff0c;能够实现高速的图像数据传输。飞凌嵌入式最新推出的OK3576-C开发板拥有丰富的资源接口&#xff0c;其中支持5个CSI-2接口&#xff0c;意味着最多可同时支持5路摄像头的输入。 本篇内容就通过OK3576-C开发板…

2024年9月CCF GESP第七次认证开启报名 6547网

CCF GESP第七次认证时间为2024年9月7日&#xff0c;1-4级认证时间为上午9:30-11:30&#xff0c;5-8级认证时间为下午13:30-16:30。7月18日17:00开启9月认证报名通道&#xff0c;考生可登录GESP官网进行报名。GESP认证方式为全国各GESP考点上机考试&#xff0c;认证语言包括&…

Monaco 使用 FoldingRangeProvider

Monaco 中支持代码折叠功能&#xff0c;FolderRangeProvider 是一个通知功能&#xff0c;编辑文档会根据大括号的范围进行折叠&#xff0c;也就是可折叠区域都是以左大括号开始&#xff0c;右大括号结束&#xff0c;当折叠区域发生变更时&#xff0c;内部方法会被调用。 通过 …