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

C++类和对象_02----对象模型和this指针

目录

  • C++对象模型和this指针
    • 1、成员变量和成员函数分开存储
      • 1.1、空类大小
      • 1.2、非空类大小
      • 1.3、结论
    • 2、this指针概念
      • 2.1、解决名称冲突
      • 2.2、在类的非静态成员函数中返回对象本身,可使用return *this
      • 2.3、拷贝构造函数返回值为引用的时候,可进行链式编程
    • 3、空指针访问成员函数
      • 3.1、访问ShowClassName()成员函数
      • 3.2、访问ShowPeopleAge()成员函数
    • 4、const修饰成员函数
      • 4.1、常函数
        • 4.1.1、 常函数本质是对this指针的修改
        • 4.1.2、成员属性声明时加关键字mutable后,可在常函数中修改
      • 4.2、常对象

C++对象模型和this指针

1、成员变量和成员函数分开存储

在C++中,类内的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象上

1.1、空类大小

class MyPeople
{
};
void Class_Func_Constructor_Member()
{MyPeople p1;cout << "空对象占用的内存空间为: " << sizeof(p1) << " 字节"<< endl;
}

运行结果:
在这里插入图片描述

C++ 会为每个空对象分配一个字节的内存空间,是为了区分空对象占内存的位置。每个空对象都有一个独一无二的地址

1.2、非空类大小

class MyPeople07
{
public:int m_a;//非静态成员变量,属于类的对象上,计算类对象大小时需要计算static int m_b;//静态成员变量,不属于类的对象上,计算类对象大小时不需要计算void func()  //非静态成员函数,不属于类的对象上 ,计算类对象大小时不需要计算{}static void func2()  //静态成员函数,不属于类的对象上 ,计算类对象大小时不需要计算{}};
void Class_Func_Constructor_Member()
{MyPeople07 p2;cout << "非空对象占用的内存空间为: " << sizeof(p2) << " 字节" << endl;
}

运行结果:
在这里插入图片描述

1.3、结论

由此可知,在类中,只有非静态成员变量才属于类的对象上,在计算类对象大小时,只需要考虑非静态成员变量的种类和个数。

2、this指针概念

在C++中成员变量和成员函数是分开存储的。每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

问题:这一块代码是如何区分那个对象调用自己的呢?
c++通过提供特殊的对象指针,this指针,解决上述问题。
(1)this指针指向被调用的成员函数所属的对象
(2)this指针是隐含每一个非静态成员函数内的一种指针
(3)this指针不需要定义,直接使用即可

this指针的用途:
(1)当形参和成员变量同名时,可用this指针来区分。解决名称冲突
(2)在类的非静态成员函数中返回对象本身,可使用return

2.1、解决名称冲突

当形参和成员变量同名时,可用this指针来区分
this指针 指向 被调用的成员函数 所属的对象

class MyPeople08
{
public:MyPeople08(int age){this->age = age;}int age;
};
void Class_Func_Constructor_this_ptr()
{//解决名称冲突MyPeople08 p1(10);cout << "p1 AGE : " << p1.age << endl;
}

运行结果:
在这里插入图片描述

2.2、在类的非静态成员函数中返回对象本身,可使用return *this

class MyPeople09
{
public:MyPeople09(int age){this->age = age;}MyPeople09& PeopleAddAge(MyPeople09 &p){this->age += p.age;return *this; //this 是指向对象的指针,*this就是对象本身}int age;
};
void Class_Func_Constructor_this_ptr()
{//返回对象本身用 *thisMyPeople09 p1(10);cout << "p1 AGE : " << p1.age << endl;MyPeople09 p2;p2.PeopleAddAge(p1);cout << "p2 AGE : " << p2.age << endl;
}

运行结果:
在这里插入图片描述

2.3、拷贝构造函数返回值为引用的时候,可进行链式编程

class MyPeople08
{
public:MyPeople08(int age){this->age = age;}MyPeople08& PeopleAddAge(MyPeople08 &p){this->age += p.age;return *this;}int age;
};
void Class_Func_Constructor_this_ptr()
{MyPeople08 p1(10);cout << "p1 AGE : " << p1.age << endl;MyPeople08 p2(10);cout << "p2 AGE : " << p2.age << endl;//链式调用p2.PeopleAddAge(p1).PeopleAddAge(p1).PeopleAddAge(p1);cout << "链式调用后 p2 AGE : " << p2.age << endl;
}

运行结果:
在这里插入图片描述

注意:当拷贝构造函数返回值为类名时,结果如下
在这里插入图片描述

原因:
MyPeople08 对象 作为返回值会触发编译器提供的浅拷贝返回的对象跟原来的对象不是同一块内存
MyPeople08 & 对象 作为返回值,那么接收的变量就是原来对象的一个别名,操纵同一块内存
链式调用目的是 在原数据改变的基础上 递增 ,引用是地址传递 会改变原有的值,不用引用就变成复制操作了

3、空指针访问成员函数

class MyPeople09
{
public:void ShowClassName(){cout << "This is MyPeople09 class !" << endl;}void ShowPeopleAge(){cout << "age = " << this->m_Age << endl;}int m_Age;
};

3.1、访问ShowClassName()成员函数

void Class_Func_Constructor_nullptr_func()
{MyPeople09 *p1 = NULL;p1->ShowClassName();
}

运行结果:
在这里插入图片描述

3.2、访问ShowPeopleAge()成员函数

void Class_Func_Constructor_nullptr_func()
{MyPeople09 *p1 = NULL;p1->ShowPeopleAge();
}

报错!!!
在这里插入图片描述
因为对于传入的指针为NULL函数来说,
其中的 cout << "age = " << m_Age << endl;相当于 cout << "age = " << this->m_Age << endl; 默认会自动加上this指针
此时,调用该函数时,传入的指针为NULL,再通过NULL->m_Age访问,就会出现问题。

修改方式如下:
在传入的指针为NULL函数中增加对空指针的判断即可

 void ShowPeopleAge(){//解决方式:增加对空指针的判断if (this == NULL){return;}cout << "age = " << this->m_Age << endl;}

4、const修饰成员函数

4.1、常函数

成员函数后加const后我们称为这个函数为常函数

特性:
1、常函数内不可以修改成员属性
2、成员属性声明时加关键字mutable后,在常函数中依然可以修改

4.1.1、 常函数本质是对this指针的修改

this指针的本质是一个 “指针常量”( MyPeople10 * const this ),表示:指针的指向不可修改;
在常函数中,该指针被进一步限定为 : const MyPeople10 * const this 表示:指针的指向不可修改并且指向的内容不能被修改。
此时,如果通过this指针修改成员变量的值,编译器会报错:不可修改的左值。如图:
在这里插入图片描述

4.1.2、成员属性声明时加关键字mutable后,可在常函数中修改

在这里插入图片描述

4.2、常对象

声明对象前加const 称该对象为 常对象

void Class_Func_Constructor_const_func()
{const MyPeople10 p1; 	//在对象前加 const 即为 常对象//p1.m_A = 123;  		//不可修改普通成员变量p1.m_B = 789;        	//mutable特殊变量,在常对象中可以修改值p1.ShowMyPeople10Class();  //常对象只能调用常函数p1.func();  //
}

常对象只能调用常函数
在这里插入图片描述

相关文章:

C++类和对象_02----对象模型和this指针

目录C对象模型和this指针1、成员变量和成员函数分开存储1.1、空类大小1.2、非空类大小1.3、结论2、this指针概念2.1、解决名称冲突2.2、在类的非静态成员函数中返回对象本身&#xff0c;可使用return *this2.3、拷贝构造函数返回值为引用的时候&#xff0c;可进行链式编程3、空…...

瑞芯微RK3568开发:烧录过程

进入rk3568这款芯片的烧录模式共有3种方式&#xff0c;先讲需要准备的环境要求。 一、软硬件环境 1、配套sdk版本的驱动DriverAssitant_vx.x.x和RKDevTool_Release_vx.x&#xff0c;版本不对应可能无法烧录&#xff0c;建议直接在sdk压缩包里获取&#xff1b; 2、如果正确安…...

【数据结构】——树和二叉树的概念

目录 1.树概念及结构 1.1树的概念 1.2 树的相关性质 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构 2.1二叉树概念 2.2 特殊的二叉树 2.3 二叉树的性质 1.树概念及结构 1.1树的概念 树是一种非线性的数据结构…...

Meta分析在生态环境领域里的应用

Meta分析&#xff08;Meta Analysis&#xff09;是当今比较流行的综合具有同一主题的多个独立研究的统计学方法&#xff0c;是较高一级逻辑形式上的定量文献综述。20世纪90年代后&#xff0c;Meta分析被引入生态环境领域的研究&#xff0c;并得到高度的重视和长足的发展&#x…...

PrivateLoader PPI服务发现RisePro恶意软件窃取分发信息

称为PrivateLoader的按安装付费&#xff08;PPI&#xff09;软件下载器服务正用于恶意软件RisePro的信息窃取。Flashpoint 于 2022 年 12月13日发现了新的窃取者&#xff0c;此前发现了在名为Russian Market的非法网络犯罪市场上使用该恶意软件泄露的“几组日志”。RisePro是一…...

SQL93 返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(一)

描述你想知道订购 BR01 产品的日期&#xff0c;有表OrderItems代表订单商品信息表&#xff0c;prod_id为产品id&#xff1b;Orders表代表订单表有cust_id代表顾客id和订单日期order_date&#xff1b;Customers表含有cust_email 顾客邮件和cust_id顾客idOrderItems表prod_idorde…...

Git ---- 概述

Git ---- 概述1. 何为版本控制2. 为什么需要版本控制3. 版本控制的工具集中式版本控制工具分布式版本控制工具4. Git 简史5. Git 工作机制6. Git 和代码托管中心Git 是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目。 Git 易于学…...

用 tensorflow.js 做了一个动漫分类的功能(二)

前言&#xff1a;前面已经通过采集拿到了图片&#xff0c;并且也手动对图片做了标注。接下来就要通过 Tensorflow.js 基于 mobileNet 训练模型&#xff0c;最后就可以实现在采集中对图片进行自动分类了。这种功能在应用场景里就比较多了&#xff0c;比如图标素材站点&#xff0…...

小林coding

一、图解网络 问大家&#xff0c;为什么要有TCP/Ip网络模型&#xff1f; 对于同一台设备上的进程通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff0c;对于不同设备上的进程通信&#xff0c;就需要有网络通信&#xff0c;而设备是…...

操作系统真相还原_第6章:完善内核

文章目录6.1 函数调用约定简介6.2 汇编语言和C语言混合编程汇编调用CC调用汇编6.3 实现打印函数流程程序编译并写入硬盘执行6.4 内联汇编简介汇编语言AT&T语法基本内联汇编扩展内联汇编6.1 函数调用约定简介 调用约定&#xff1a; calling conventions 调用函数时的一套约…...

SmoothNLP新词发现算法的改进实现

SmoothNLP新词发现算法的改进实现 背景介绍 新词发现也叫未登录词提取&#xff0c;依据 《统计自然语言处理》(宗成庆)&#xff0c;中文分词有98%的错误来自"未登录词"。即便早就火遍大江南北的Bert也不能解决"未登录词"的Encoding问题&#xff0c;便索性…...

实时渲染为什么快,能不能局域网部署点量云

提到渲染很多有相关从业经验的人员可能会想起&#xff0c;自己曾经在电脑上渲染一个模型半天或者更长的 时间才能完成的经历。尤其是在项目比较着急的时候&#xff0c;这种煎熬更是难受。但现在随着实时渲染和云渲染行业的发展&#xff0c;通过很多方式可以提升渲染的时间和效率…...

网络游戏该如何防护ddos/cc攻击

现在做网络游戏的企业都知道服务器的安全对于我们来说很重要&#xff01;互联网上面的 DDoS 攻击和 CC 攻击等等无处不在&#xff0c;而游戏服务器对服务器的防御能力和处理能力要求更高&#xff0c;普通的服务器则是比较注重各方面能力的均衡。随着游戏行业的壮大&#xff0c;…...

项目管理体系1-4练习题1-10答案

题目1 每周一次的项目会议上&#xff0c;一位团队成员表示在修订一项可交付成果时&#xff0c;一名销售经理对客户服务过程想出一项变更讨论&#xff0c;影响到整个项目&#xff0c;项目经理对销售参与到项目可交付成果感到吃惊&#xff0c;经理事先应该怎么做去阻止这些情况&…...

sHMIctrl智能屏幕使用记录

手上有个案子&#xff0c;“按压机器人”&#xff0c;功能是恒定一个力按下一定时间。 屏幕选型使用“sHMIctrl”&#xff0c;一下记录使用过程中遇到的问题以及解决方法。 目录 问题1&#xff1a;按键控件做定时触发&#xff0c;模拟运行时触发不了。 问题2&#xff1a;厂家…...

2.20 crm day01 配置路由router less使用 axios二次封装

需求&#xff1a; 目录 1.配置路由 2.less使用 vue2使用以下版本 3.axios二次封装 1.配置路由 1.1.1 官方链接&#xff1a;安装 | Vue Router npm i vue-router3.6.5 注意&#xff1a;vue2项目不能用vue-router四版本以上 1.2.1.创建router/index.js 在该文件中 //1.引…...

【LeetCode】剑指 Offer 10- I. 斐波那契数列 p74 -- Java Version

题目链接&#xff1a; 1. 题目介绍&#xff08;&#xff09; 写一个函数&#xff0c;输入 n &#xff0c;求斐波那契&#xff08;Fibonacci&#xff09;数列的第 n 项&#xff08;即 F(N)&#xff09;。斐波那契数列的定义如下&#xff1a; F(0) 0, F(1) 1F(N) F(N - 1) F…...

论文笔记:DropMessage: Unifying Random Dropping for Graph Neural Networks

&#xff08;AAAI 23 优秀论文&#xff09; 1 intro GNN的一个普遍思路是&#xff0c;每一层卷积层中&#xff0c;从邻居处聚合信息 尽管GNN有显著的进步&#xff0c;但是在大规模图中训练GNN会遇到各种问题&#xff1a; 过拟合 过拟合之后&#xff0c;GNN的泛化能力就被限制…...

木鱼cms系统审计小结

MuYuCMS基于Thinkphp开发的一套轻量级开源内容管理系统,专注为公司企业、个人站长提供快速建站提供解决方案。 ​​ ‍ 环境搭建 我们利用 phpstudy 来搭建环境&#xff0c;选择 Apache2.4.39 MySQL5.7.26 php5.6.9 &#xff0c;同时利用 PhpStorm 来实现对项目的调试 ​…...

软件测试面试-一线大厂必问的测试思维面试题

五、测试思维5.1 打电话功能怎么去测&#xff1f;我们会从几个方面去测试&#xff1a;界面、功能、兼容性、易用性、安全、性能、异常。1&#xff09;界面我们会测试下是否跟界面原型图一致&#xff0c;考虑浏览器不同显示比例&#xff0c;屏幕分辨率。2&#xff09;功能&#…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...