Cpp中的this指针--复习记录

news2024/9/24 19:19:17

1.什么是this指针?

    每个类都有一个this指针,我们的非静态成员函数可以通过这个this指针来操作对象的成员属性。this指针存储的就是类的实例的地址,this指针时时刻刻指向的都是这个实例对象本身。

由下图可知:

我在主函数中栈上创建了一个类的实例(由操作系统自动回收释放),然后再用s调用learn打印出当前this指针的地址,由终端可见,此时类对象地址与this指针的地址是相同的。

这样我们知道了this指针的基本概念,再来说说他的具体用途:

 1.当形参和成员变量同名时

可以用this指针来区分。如下图所示 ,这样就可以将传入的sum值赋值给类的成员变量。

2.在类的非静态成员函数中返回对象本身,可以使用return *this来返回当前对象的引用,这种技术被称为链式调用(chaining),它允许在调用对象的成员函数后,直接继续调用另一个函数。

链式调用的好处:

  • 代码简洁清晰: 可以在一行代码中完成多个对象状态的修改,使代码更加紧凑。
  • 可读性增强: 易于理解对象状态的设置顺序和逻辑。
  • 便于使用 fluent API: 在设计 fluent interface 时非常有用,提供一种流畅的接口风格。
  • Fluent Interface 是一种优雅的设计模式,通过返回对象自身的引用实现了链式调用,提升了代码的可读性和编写效率。它特别适合用于需要频繁进行多步设置的场景,能够简化代码结构,使其更具表达力和清晰度。

3.看看这一段代码

他可以正常打印输出吗?

    class A
    {
        int i;
        public:
        void Hello() 
        { 
            cout << "hello" << endl; 
        }
    };
    
    int main()
    {
        A * p = NULL;
        p->Hello(); //结果会怎样?
    }

答案是可以的,你可能会好奇,明明p是空指针,为什么还能正常打印呢?

实际上每个成员函数的第一个参数默认都有个指向对象的 this 指针,上述情况下如果该指向的对象是空,相当于成员函数的第一个参数是NULL,那么只要成员函数没有使用到成员变量,也是可以正常执行。

但倘若加上i ,就会报错啦。因为this指针是空的,使用了空的指针指向了成员变量i,程序就会奔溃。

3.要注意,静态成员函数不可以使用this指针,因为静态成员函数相当于是共享的变量,不属于摸个对象的变量,而this存储的是对象的地址,它指向的就是对象,所以静态成员函数它是没有this指针的。

说到这了,

2.什么是static,它的用法有哪些呢?

static是从C/C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

引入static:

我们知道在函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配内存空间,函数在栈上分配的内存空间在此函数结束之后就会被释放掉,这样就产生了一个问题,如果想将函数中的变量保存值下一次调用时,改如何实现呢? 最容易想到的方法是定义一个全局的变量,但定义一个全局的变量有许多缺点,最明显的缺点就是破坏的次变量的访问范围,(使得此函数的变量不仅仅只受此函数的控制),static关键字则可以很好的解决这个问题。

另外,在C++中如果需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可以将其定义为静态数据。

将成员变量和成员函数设置为static,他就不属于任何对象,而是属于这个类了,被类的实例所共享,成员变量分为

1.可见类内静态成员需要在类外进行初始化,(C++11标准之前),现在可以将静态成员在类内进行初始化,只不过需要加上const。

static的基本用法:

1、被 static 修饰的变量属于类变量,可以通过类名::变量名直接引用,而不需要 new 出一个类来

2、被 static 修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要 new 出一个类来而非静态成员不可以直接用类名直接调用。

使用static的几种情况总结:

  1. 修饰变量

  • 全局变量:

  • 链接属性由外部变成内部,即对其他文件不可见,只能在本文件使用。

  • 局部变量:

  • 作用域不变,生命周期变成整个程序的执行周期,在内存中的位置由栈区变为全局静态区。退出作用域,该变量不可访问,但是仍在内存中;如果再次进入作用域,则读取上次的结果继续使用。

  • 成员变量:

  • 必须在类外初始化(static成员变量先于类的对象存在,static程序启动时就在内存中,而对象需要等到执行到的时候才会在内存中),该变量在类的所有对象中共享,只存在一份。可以通过类名+作用域的形式访问。

  1. 修饰函数

  • 普通函数:

  • 链接属性由外部变成内部,即对其他文件不可见,只能在本文件使用。

  • 成员函数:

  • 该函数在类的所有对象中共享,只存在一份,可以通过类名+作用域形式访问。没有this指针无法声明为虚函数、常函数,无法直接访问非静态成员变量(可通过对象的方式访问),无法调用非静态成员函数。如下图所示:

3.const的作用:

基本概念:

const允许我们指定一个语义约束,告诉编译器某个对象不应该被改变,而编译器会帮助我们实施这一项约束,如果我们认定某个值不能被改变,那么我们就应该使用const,来让编译器帮助我们来保证这个条件不会被违反。

适用场景:

const可以修饰很多内容,对于修饰变量,可以修饰局部的(必须立刻初始化,否则编译错误),全局的(默认初始化为0)或者成员变量(必须使用构造函数的初始化列表进行初始化),对于函数,可以修饰函数的返回值,函数的参数,对于指针,可以修饰指针本身,也可以修饰指针所指向的对象;对于类,可以修饰类的成员变量,也可以修饰类的成员函数。

举例说明:

比如我们重写一个操作符*,我们就应该把这个函数的返回值设置为const,因为我们知道这个操作符的返回值是不可以更改的,这样就可以避免一些错误的语法,比如a*b=c,(可能我们只是想判断a*b和c是否相等,但是误写成了=)。

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

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

相关文章

数据规模介绍

batch_size 2 1829*2 3658张图片 FSC147数据集介绍 train 3659 val 1286 test 1190

xxl-job 源码梳理(2)-服务端

目录 1. 控制面的接口2.手动触发任务2. 定时任务的实现 1. 控制面的接口 服务端包含xxl-job的管理端&#xff0c;页面上的接口后端一系列的controller接口 appName是一个核心概念&#xff0c;它是指执行器应用的名称&#xff0c;appName是执行器的唯一标识 页面上的接口&#…

出行365:依托分布式数据库,让出行无忧 | OceanBase案例

*本文首发自“新华社环球”杂志&#xff0c;作者张海鑫 每年的暑期旅游旺季&#xff0c;都会触发一轮轮的文旅消费的热潮&#xff0c;对于互联网出行服务行业而言&#xff0c;这既是一场盛大的狂欢&#xff0c;也是对其综合实力的严峻考验。 然而&#xff0c;自去年暑假起&…

Email发送接口安全性保障策略?如何优化?

Email发送接口的高级功能&#xff1f;怎么有效利用邮件API接口&#xff1f; Email发送接口的安全性对于防止数据泄露、滥发垃圾邮件和恶意攻击至关重要。AokSend将探讨Email发送接口的安全性保障策略&#xff0c;帮助开发者和企业确保其电子邮件通信的安全性和可靠性。 Email…

智能猫砂盆买错有什么危害?深度解析三款热门爆款产品!

作为一名家里还有小猫在等待的上班族&#xff0c;我们经常因为需要加班或频繁出差而忙碌得不可开交&#xff0c;导致我们很容易忽略猫咪的厕所环境和健康安全&#xff0c;每次急匆匆地出门&#xff0c;都发现自己似乎忘了给猫咪及时铲屎。但是大家要知道&#xff0c;不及时清理…

为人处世,“会说话”是一生的修行

职场上&#xff0c;常常存在这样一种现象&#xff1a;“会干活的&#xff0c;不如会说的。” 学会“好好说话”、“说正确的话”“说让人舒服的话”成为一生必须要面对的修行。 01 丰厚的学养&#xff0c;是“会说话”的根基。 同一句话&#xff0c;“会说话”的人&#xf…

XXXForm组件

效果展示 代码 XXXForm <template><div class"search-container"><el-form ref"formRef" class"form_is_hidden" :model"form" v-bind"formAttrs"><el-row :gutter"20" class"search…

一文带你快速了解——LVS负载均衡集群

前言&#xff1a; Internet的飞速发展给网络带宽和服务器带来巨大的挑战。从网络技术的发展来看&#xff0c;网络带宽的增长远高于处理器速度和内存访问速度的增长。对用硬件和软件方法实现高可伸缩、高可用网络服务的需求不断增长。针对高可伸缩、高可用网络服务的需求&#x…

.NET8使用VS2022打包Docker镜像

NET8使用VS2022打包Docker镜像 1. 项目中添加Docker支持文件2. 自定义镜像名称3. 发布Docker镜像3.1 安装Docker3.2 控制台切换到项目根目录,执行以下命令发布镜像 3.3 修改镜像名称4. 保存镜像到本地 1. 项目中添加Docker支持文件 2. 自定义镜像名称 项目文件PropertyGroup节…

软件功能测试步骤介绍,软件测试服务公司推荐

在当今软件开发日益复杂的环境中&#xff0c;软件功能测试显得尤为重要。功能测试是确保软件产品满足用户需求和规范要求的关键环节。它通过验证软件功能是否按预期运行&#xff0c;帮助发现潜在的问题&#xff0c;防止软件在上线后导致用户的不满及业务损失。随着市场竞争的加…

(el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程

Ⅰ、Element-plus 提供的DatePicker日期选择器组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供DatePicker组件情况&#xff1a; 其一、Element-ui 自提供的DatePicker代码情况为(示例的代码)&#xff1a; // Element-plus 提供的组件代码: <template><e…

【多线程-从零开始-捌】代码案例2—阻塞队列

什么是阻塞队列 阻塞队里是在普通的队列&#xff08;先进先出队列&#xff09;基础上&#xff0c;做出了扩充 线程安全 标准库中原有的队列 Queue 和其子类&#xff0c;默认都是线程不安全的 具有阻塞特性 如果队列为空&#xff0c;进行出队列操作&#xff0c;此时就会出现阻…

Java代码生成器EasyCode

Java代码生成器EasyCode 一、安装插件二、连接数据库后右键Generator生成代码 一、安装插件 在 IntelliJ IDEA 的插件市场中搜索 EasyCode&#xff0c;然后安装该插件 二、连接数据库后右键Generator生成代码 勇敢面对挑战&#xff0c;成功从不会远离坚持者。坚持不懈的努力…

八股之Java集合

Java 集合&#xff0c;也叫作容器&#xff0c;主要是由两大接口派生而来&#xff1a;一个是 Collection接口&#xff0c;主要用于存放单一元素&#xff1b;另一个是 Map 接口&#xff0c;主要用于存放键值对。对于Collection 接口&#xff0c;下面又有三个主要的子接口&#xf…

MongoDB学习笔记(三)

使用Python操作MongoDB: 使用管理员用户&#xff1a;

Python —— 基础

目录 变量与引用 数据类型 赋值、深浅拷贝 控制流结构 逻辑操作符 is 与 dir() 关键字&#xff08;Python 3.11 &#xff09; https://www.cnblogs.com/qianfanwaer/p/14783204.html 变量与引用 变量是原来存储数据的一个标识符&#xff0c;可被看作是内存的一个位置&…

【学习笔记】Day 7

一、进度概述 1、DL-FWI基础入门培训笔记 2、inversionnet_train 试运行——未成功 二、详情 1、InversionNet: 深度学习实现的反演 InversionNet构建了一个具有编码器-解码器结构的卷积神经网络&#xff0c;以模拟地震数据与地下速度结构的对应关系。 &#xff08;一…

Python,我来啦!!!融合多个框架语言。。

基于上次发布CSDN的自己一些想法 上次&#xff0c;从一个道友手中购买了一份轮子代码&#xff0c;主要用到的技术就是pythonmysql或sqliteflask框架&#xff0c;这里我做了二次开发。 新的改变 这里&#xff0c;我对该代码进行了一些功能拓展与语法支持&#xff0c;除了原有…

【OpenCV C++20 学习笔记】仿射变换-warpAffine, getRotationMatrix2D

仿射变换 原理概述得到仿射变换的方法 APIgetAffineTransform()函数warpAffine()函数getRotationMatrix2D()函数 示例 原理 概述 仿射变换是矩阵乘法&#xff08;线性变换&#xff09;和向量加法的结合。它包含了&#xff1a; 旋转&#xff08;线性变换&#xff09;转换&…

【递归 + 记忆化搜索优化】力扣494. 目标和

给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 ‘’ &#xff0c;在 1 之前添加 ‘-…