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

【C++】C++ 类中的 this 指针用法 ③ ( 全局函数 与 成员函数 相互转化 | 有参构造函数设置默认参数值 | 返回匿名对象与返回引用 )

文章目录

  • 一、全局函数 与 成员函数 相互转化
    • 1、成员函数转为全局函数 - 多了一个参数
    • 2、全局函数转为成员函数 - 通过 this 指针隐藏操作数
  • 二、有参构造函数设置默认参数值
  • 三、返回匿名对象与返回引用
  • 四、完整代码示例





一、全局函数 与 成员函数 相互转化




1、成员函数转为全局函数 - 多了一个参数


C++ 编译器 , 在编译阶段会将 C++ 类的 成员函数 转为 全局函数 , 转换时 , 会 增加一个参数到参数列表开始为止 , 这个增加的参数是 对象本身的指针 ;


在 Student 类中 , 定义了如下函数 :

	// 成员函数 转为 全局函数 , 多了一个参数 Student* pThis 作为第一个参数void print(){cout << "age = " << this->age << " , height = " << this->height << endl;}

将上述 Student 类 中的 print 成员函数 , 转为 全局函数 , 转换后的代码为 :

// 将成员函数 void print() 
// 转为 全局函数
void Student_print(Student* pThis)
{cout << "age = " << pThis->age << " , height = " << pThis->height << endl;
}

转换完毕后 , 参数列表中增加了一个参数 Student* pThis 在 列表的开始位置 ;

详细代码 , 参考最后的完整代码示例 ;


2、全局函数转为成员函数 - 通过 this 指针隐藏操作数


全局函数转为成员函数 , 需要隐藏一个参数 , 就是通过 this 指针隐藏左操作数 , 对象本身 就是 左操作数 , 在成员函数中 , 通过 this 指针访问对象本身的成员 ;


在全局函数中 , 实现两个 Student 类相加 , 接收两个 Student 引用类型的参数 , 引用相当于一级指针 ;

// 全局函数中 , 将两个 Student 对象相加
// 引用的 等同于 一级指针 , Student 引用用法与 Student 对象用法相同
// 全局函数 转为 成员函数 , 少了一个参数
Student StudentPlus(Student& s1, Student& s2)
{Student s;s.age = s1.age + s2.age;s.height = s1.height + s2.height;return s;
}

转为成员函数后 , 成员函数 比 全局函数 少了一个参数 , 少的那个参数 , 就是对象本身 ;

	// 成员函数中, 将两个 Student 对象相加// 全局函数 转为 成员函数 , 少了一个参数Student StudentPlus(Student& s2){Student s;s.age = this->age + s2.age;s.height = this->age + s2.height;// 注意 : 返回的是一个匿名对象return s;}

详细代码 , 参考最后的完整代码示例 ;





二、有参构造函数设置默认参数值



为 Student 类定义了有参构造函数 , 则其默认的无参构造函数 , 就不会生成 ;

	// 带参构造函数Student(int age, int height){this->age = age;this->height = height;cout << "执行 Student 的构造函数" << endl;}

此时 , 如果要创建 Student 对象 , 只能调用上述 有参构造函数 , 如果使用 Student s2 的方式调用 默认构造函数 创建 Student 对象 , 就会报错 ;

在这里插入图片描述


如下带参数的构造函数 , 并且为其 有参构造函数 的参数 设置一个默认值 , 此时就可以使用 类名 对象名 的方式定义对象变量 ;

class Student
{
public:// 带参构造函数Student(int age = 0, int height = 0){this->age = age;this->height = height;cout << "执行 Student 的构造函数" << endl;}~Student(){cout << "执行 Student 的析构函数" << endl;}public:int age;		// 年龄int height;		// 身高
};

此时就可以使用默认构造函数 , 创建 Student 对象 ;

在这里插入图片描述





三、返回匿名对象与返回引用



在上面的章节中 , 将 两个 Student 对象相加 , 返回的是一个匿名对象 , 该匿名对象 是在 成员函数 中新创建的对象 ;

	// 成员函数中, 将两个 Student 对象相加// 全局函数 转为 成员函数 , 少了一个参数// 返回一个新 Student 对象Student StudentPlus(Student& s2){Student s;s.age = this->age + s2.age;s.height = this->height + s2.height;// 注意 : 返回的是一个匿名对象return s;}

如果不返回新的对象 , 而是将 两个 对象相加 , 最终结果累加到 本对象中 , 则返回 Student 引用即可 ;

	// 成员函数中, 将两个 Student 对象相加// 全局函数 转为 成员函数 , 少了一个参数// 两个 对象相加 , 最终结果累加到 本对象中Student& StudentPlus2(Student& s2){this->age = this->age + s2.age;this->height = this->height + s2.height;// 注意 : 返回的是一个引用 , 就是返回自身对象变量// this 是指针 , *this 是指针指向的 自身对象return *this;}

返回 引用 , 就是返回自身对象 ;

this 是指针 , *this 是指针指向的 自身对象 实际数据 ,

返回引用 , 就是返回 自身对象实际数据 *this ;





四、完整代码示例



代码示例 :

#include "iostream"
using namespace std;class Student
{
public:// 带参构造函数Student(int age = 1, int height = 1){this->age = age;this->height = height;cout << "执行 Student 的构造函数" << endl;}~Student(){cout << "执行 Student 的析构函数" << endl;}// 成员函数中, 将两个 Student 对象相加// 全局函数 转为 成员函数 , 少了一个参数// 返回一个新 Student 对象Student StudentPlus(Student& s2){Student s;s.age = this->age + s2.age;s.height = this->height + s2.height;// 注意 : 返回的是一个匿名对象return s;}// 成员函数中, 将两个 Student 对象相加// 全局函数 转为 成员函数 , 少了一个参数// 两个 对象相加 , 最终结果累加到 本对象中// 注意此处 : 函数重载 不以 返回值为标准 , 函数名需要修改Student& StudentPlus2(Student& s2){this->age = this->age + s2.age;this->height = this->height + s2.height;// 注意 : 返回的是一个引用 , 就是返回自身对象变量// this 是指针 , *this 是指针指向的 自身对象return *this;}// 成员函数 转为 全局函数 , 多了一个参数 Student* pThis 作为第一个参数void print(){cout << "age = " << this->age << " , height = " << this->height << endl;}public:int age;		// 年龄int height;		// 身高
};// 将成员函数 void print() 
// 转为 全局函数
void Student_print(Student* pThis)
{cout << "age = " << pThis->age << " , height = " << pThis->height << endl;
}// 全局函数中 , 将两个 Student 对象相加
// 引用的 等同于 一级指针 , Student 引用用法与 Student 对象用法相同
// 全局函数 转为 成员函数 , 少了一个参数
Student StudentPlus(Student& s1, Student& s2)
{Student s;s.age = s1.age + s2.age;s.height = s1.height + s2.height;return s;
}int main() {// 调用有参构造函数 创建 Student 实例对象Student s(18, 180);// 打印对象情况s.print();// 调用有参构造函数 , 有参构造函数参数使用默认值Student s2;s2.print();// 调用全局函数, 将两个 Student 对象相加// 函数返回的 匿名对象 用于 s3 初始化 // 直接将匿名对象转为普通对象Student s3 = StudentPlus(s, s2);s3.print();// 调用成员函数, 将两个 Student 对象相加Student s4;// 函数返回的 匿名对象 用于 s4 赋值// 此处匿名对象 为 s4 赋值 , 赋值完毕后 匿名对象销毁s4 = s.StudentPlus(s2);s3.print();// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}

执行结果 :

执行 Student 的构造函数
age = 18 , height = 180
执行 Student 的构造函数
age = 1 , height = 1
执行 Student 的构造函数
执行 Student 的析构函数
age = 19 , height = 181
执行 Student 的构造函数
执行 Student 的构造函数
执行 Student 的析构函数
执行 Student 的析构函数
age = 19 , height = 181
请按任意键继续. . .

在这里插入图片描述

相关文章:

【C++】C++ 类中的 this 指针用法 ③ ( 全局函数 与 成员函数 相互转化 | 有参构造函数设置默认参数值 | 返回匿名对象与返回引用 )

文章目录 一、全局函数 与 成员函数 相互转化1、成员函数转为全局函数 - 多了一个参数2、全局函数转为成员函数 - 通过 this 指针隐藏操作数 二、有参构造函数设置默认参数值三、返回匿名对象与返回引用四、完整代码示例 一、全局函数 与 成员函数 相互转化 1、成员函数转为全局…...

游戏遇到的问题

天涯明月刀 就是天刀的假全屏&#xff0c;很多天刀玩家可能玩其他游戏比较少或者对电脑了解不多&#xff0c;不在意帧数&#xff0c;但是肯定还是有一部分玩家发现了这个问题&#xff0c;就是“我使命召唤12都能跑到60帧的机器跑个破天刀40帧甚至30帧?”问题何在呢&#xff1…...

高性能系统的性能优化技巧:从专家的经验中学习 | 开源日报 No.40

binhnguyennus/awesome-scalability Stars: 48.3k License: MIT 这个项目是一个阅读列表&#xff0c;用于说明可扩展、可靠和高性能大规模系统的模式。该项目通过知名工程师的文章和可信参考资料来解释概念&#xff0c;并从为数以百万计甚至十亿用户提供服务的经过实战验证的系…...

Linux系统编程——进程间通信的学习

学习参考博文&#xff1a; 进程间的五种通信方式介绍Linux 信号介绍 Linux系统编程学习相关博文 Linux系统编程——文件编程的学习Linux系统编程——进程的学习Linux系统编程——线程的学习Linux系统编程——网络编程的学习 Linux系统编程——进程间通信的学习 一、概述1. 无…...

人工智能AI 全栈体系(六)

第一章 神经网络是如何实现的 这些年神经网络的发展越来越复杂&#xff0c;应用领域越来越广&#xff0c;性能也越来越好&#xff0c;但是训练方法还是依靠 BP 算法。也有一些对 BP 算法的改进算法&#xff0c;但是大体思路基本是一样的&#xff0c;只是对 BP 算法个别地方的一…...

NPDP是什么?考了有用吗?

1&#xff09;NPDP是什么&#xff1f; NPDP&#xff0c;全称为New Product Development Professional&#xff0c;即新产品开发专业人员。NPDP认证是由世界产品开发协会&#xff08;PDMA&#xff09;推出的一项专业认证。它旨在评估和认可个人在新产品开发领域的专业知识和技能…...

关于安卓SVGA浅尝(二)加载数据

关于安卓SVGA浅尝&#xff08;二&#xff09;加载数据 相关链接 SVGA官网 SVGA-github说明文档 背景 项目开发&#xff0c;都会和动画打交道&#xff0c;动画的方案选取&#xff0c;就有很多选择。如Json动画&#xff0c;svga动画&#xff0c;gif等等。各有各的优势。目前项…...

使用matlab产生二维动态曲线视频文件具体举例

使用matlab产生二维动态曲线视频文件举例 在进行有些函数变化过程时候&#xff0c;需要用到直观的动态显示&#xff0c;本博文将举例说明利用Matlab编程进行二维动态曲线的生成视频文件。 一、问题描述 利用matlab编程实现 y 1 s i n ( t ) , y 2 c o s ( t ) , y 3 s i …...

Selenium自动化测试框架常见异常分析及解决方法

01 pycharm中导入selenium报错 现象: pycharm中输入from selenium import webdriver, selenium标红 原因1: pycharm使用的虚拟环境中没有安装selenium, 解决方法: 在pycharm中通过设置或terminal面板重新安装selenium 原因2: 当前项目下有selenium.py,和系统包名冲突导致, …...

[TI] [Textual Inversion] An image is worth an word

自己的理解&#xff1a; 根据几个图像&#xff0c;找出来一个关键字可以代表它们&#xff0c;然后我们可以再用这个关键字去生成新的东西。 提出关键字 1 Introduction word->token->embedding Textual Inversion过程 需要&#xff1a; ① a fixed, pre-trained text…...

remote: The project you were looking for could not be found

git拉取公司项目时报错&#xff1a; remote: The project you were looking for could not be found 发生这个问题的原因&#xff0c;在于git账号可能并未真正登录。 我们可以通过打开电脑的凭据管理器&#xff0c;查看git当前的登录是否正常。 参考链接&#xff1a;参考...

https跳过SSL认证时是不是就是不加密的,相当于http?

https跳过SSL认证时是不是就是不加密的,相当于http?&#xff0c;其实不是&#xff0c;HTTPS跳过SSL认证并不相当于HTTP&#xff0c;也不意味着没有加密。请注意以下几点&#xff1a; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;本质上是在HTTP的基础上…...

linux下链接

linux下链接用法 ln链接格式与介绍 linux下链接用法一、链接的使用格式二、链接的介绍 一、链接的使用格式 链接&#xff1a; 格式&#xff1a; ln 源文件 链接文件 硬链接 ln -s 源文件 链接文件 软连接 硬链接文件占磁盘空间 但是删除源文件不会影响硬链接文件 软链接文件不…...

OpenCV项目开发实战--主成分分析(PCA)的特征脸应用(附C++/Python实现源码)

什么是主成分分析? 这是理解这篇文章的先决条件。 图 1:使用蓝线和绿线显示 2D 数据的主要组成部分(红点)。 快速回顾一下,我们了解到第一个主成分是数据中最大方差的方向。第二主成分是空间中与第一主成分垂直(正交)的最大方差方向,依此类推。第一和第二主成分红点(2…...

多层感知机——MLP

源代码在此处&#xff1a;https://github.com/wepe/MachineLearning/tree/master/DeepLearning Tutorials/mlp 一、多层感知机&#xff08;MLP&#xff09;原理简介 多层感知机&#xff08;MLP&#xff0c;Multilayer Perceptron&#xff09;也叫人工神经网络&#xff08;ANN&…...

HttpClientr入门

HttpClientr入门 介绍 HttpClient是Apache Jakarta Common下的子项目&#xff0c;可以用来提供高效的&#xff0c;最新的、功能丰富的支持HTTP协议的客户端编程工具包&#xff0c;并且它支持HTTP协议的版本和建议。 依赖导入 <dependency><groupId>org.apache.…...

网关-开放API接口签名验证方案

接口安全问题 请求身份是否合法&#xff1f;请求参数是否被篡改&#xff1f;请求是否唯一&#xff1f; AppId&AppSecret 请求身份 为开发者分配AppId&#xff08;开发者标识&#xff0c;确保唯一&#xff09;和AppSecret&#xff08;用于接口加密&#xff0c;确保不易被…...

Linux知识点 -- 网络基础 -- 传输层

Linux知识点 – 网络基础 – 传输层 文章目录 Linux知识点 -- 网络基础 -- 传输层一、传输层协议1.端口号2.网络相关bash命令 二、UDP协议1.UDP报文的解包与交付2.理解UDP报文3.UDP协议的特点4.UDP应用层IO类接口5.UDP的缓冲区6.UDP使用注意事项7.基于UDP的应用层协议 三、TCP协…...

计算机视觉与深度学习-经典网络解析-AlexNet-[北邮鲁鹏]

这里写目录标题 AlexNet参考文章AlexNet模型结构AlexNet共8层&#xff1a;AlexNet运作流程 简单代码实现重要说明重要技巧主要贡献 AlexNet AlexNet 是一种卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;的架构。它是由Alex Krizhevsky、Il…...

Django学习笔记-实现联机对战(下)

笔记内容转载自 AcWing 的 Django 框架课讲义&#xff0c;课程链接&#xff1a;AcWing Django 框架课。 CONTENTS 1. 编写移动同步函数move_to2. 编写攻击同步函数shoot_fireball 1. 编写移动同步函数move_to 与上一章中的 create_player 同步函数相似&#xff0c;移动函数的同…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...

Netty自定义协议解析

目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...