c++入门学习⑤——对象模型和this指针

目录

前言:

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

注意:

案例:

this指针的概念

介绍:

用途:

错误案例:

解决方案:

 注意函数为什么用引用返回呢,如果用值返回,结果会产生怎样的变化,why?

空指针访问成员函数

简介:

错误案例:

修改:

 总结:

const修饰成员函数

常函数:

常变量:

当成员函数写入const后

正常的赋值不能进行了,why?

结语:


前言:

这篇博客接着上回有关c++内容讲解有关对象模型和this指针的内容💪

传送门:

c++入门学习①-CSDN博客

c++入门学习②-CSDN博客

c++入门学习③——封装-CSDN博客

c++入门学习④——对象的初始化和清理-CSDN博客

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

成员函数成员变量分开储存
只有非静态的成员变量才属于类的对象,其余都不是类的对象

注意:

空对象所占内存为1👉因为c++编译器,会给每个空对象分配一个空间,每个空对象都应该有一个独一无二的内存地址,为了区分空对象内存的位置,所以内存空间设置为1。

空对象为1,非空对象为类里成员所占用的空间,其中只有非静态成员变量才属于类的对象中。


案例:

#include<iostream>
#include<string>
using namespace std; 
//成员函数和成员变量分开储存
// 只有非静态的成员变量才属于类的对象class person {
public:int m_a;//非静态,属于类的对象上static int m_b;void func() {//非静态成员函数,不属于类的对象}static void test() {//静态成员函数,只有一份,不属于类的对象上}
};
int person::m_b = 0;
void test1() //测试案例
{ person p;cout << sizeof(p) << endl;//空对象所占内存为1//👉因为c++编译器,会给每个空对象分配一个空间,为了区分空对象内存的位置//每个空对象都应该有一个独一无二的内存地址//有一个int成员,则对象所占空间为4//👉空对象为1,非空对象为类里属性成员所占用的空间//添加一个静态成员后发现所占内存空间仍是4,没改变//再添加一个非静态成员函数,内存还没变,仍为4,不属于类的对象//再加一个静态成员函数,内存仍为4,静态成员变量不属于类的对象上。
}int main()
{test1();system("pause");return 0;
}

this指针的概念

介绍:

成员变量和成员函数是分开存储
this指针指向被调用的成员函数所属对象
它是隐含在每一个非静态成员函数的一种指针,不须定义

用途:

1.当形参和成员变量同名时,可用this指针区分
2.返回对象本身,用*this

错误案例:

#include<iostream>
#include<string>
using namespace std; 
//成员变量和成员函数是分开存储的
//this指针指向被调用的成员函数所属对象
//隐含在每一个非静态成员函数的一种指针,不须定义
//用途:当形参和成员变量同名时,可用this指针区分
//返回对象本身,用*thisclass person {
public:person(int age) {//构造函数初始化对象age = age;}int age;
};void test1() //测试案例
{ person p1(12);cout << "p1年龄" << p1.age << endl;//输出一个长串数字,其实实际上age未真正赋值
}int main()
{test1();system("pause");return 0;
}

解决方案:

1.把int age改为int m_age; 

2.加一个this

示例:

class person {
public:person(int age) {//构造函数初始化对象this->age = age;
/*this指针指向被调用成员函数所属对象,下面person p1(12)是调用的函数,
这个函数是p1在调用,this指向p1。
*/}int age;
};

用*this 返回对象示例:

#include<iostream>
#include<string>
using namespace std; 
//成员变量和成员函数是分开存储的
//this指针指向被调用的成员函数所属对象
//隐含在每一个非静态成员函数的一种指针,不须定义
//用途:当形参和成员变量同名时,可用this指针区分
//返回对象本身,用*thisclass person {
public:person(int age) {//构造函数初始化对象this->age = age;}person& personaddage(person& p) {this->age += p.age;//所调用这个函数的对象的年龄加上所输入的年龄=所调用这个函数的对象的年龄return *this;}//返回本体,用引用的方式返回int age;
};void test1() //测试案例
{ person p1(10);person p2(10);p2.personaddage(p1);//p2调用函数personaddage,结果为20//执行完函数如果返回调用函数的对象,则可以实现无限增加年龄p2.personaddage(p1).personaddage(p1).personaddage(p1);cout << p2.age << endl;//结果为40
}int main()
{test1();system("pause");return 0;
}

 注意函数为什么用引用返回呢,如果用值返回,结果会产生怎样的变化,why?

返回值则结果为20👉
返回值则按照对象自身拷贝构造一个新的数据,构造返回值,每一次都是一个新对象

引用会返回这个原本的对象而不会和返回值一样创建一个新的对象。

空指针访问成员函数

简介:

空指针可以调用成员函数,但由于有this指针,容易有坑,出错。

错误案例:

#include<iostream>
#include<string>
using namespace std; 
//空指针可以调用成员函数,但由于有this指针,容易有坑class person {
public:void classname() {cout << "this is person class" << endl;}void personage() {cout << "age=" <<m_age<< endl;//存在类属性,其实在属性的前面默认都会加上一个this->,空指针调用这个函数,导致this没有指向一个确切的值}int m_age;
};void test1() 
{ person* p=NULL;p->classname();//只有这一个函数时,程序不崩p->personage();//这个函数出错,程序崩溃了,报错原因是传入指针为空//如何解决呢?
}int main()
{test1();system("pause");return 0;//代码崩了
}

修改:

 void personage() {if (this == NULL) {return;}cout << "age=" <<m_age<< endl;//存在类属性,其实在属性的前面默认都会加上一个this->,空指针调用导致this没有指向一个确切的值}int m_age;

 总结:

提高代码的健壮性用if来预防有空指针的调用,空指针可以访问,但是不可以去使用在正常的带属性的一个成员函数内,会导致程序崩溃的

const修饰成员函数

用const修饰成员函数则成员函授叫做:常函数

用const修饰成员变量则成员变量叫做:常变量

常函数:

1.成员函数括号后加上const,修饰对象为this指针

2.常函数不可以修改成员属性

3.如果要修改成员属性,成员属性前必须要加上关键字mutable

常变量:

1.声明对象前加上const则称为常对象

2.常对象只能调用常函数,因为普通函数可以修改成员属性,而常函数不可以修改一般成员属性,因此常对象不可调用常函数。

当成员函数写入const后

正常的赋值不能进行了,why?

每一个成员函数都有一个this指针,this指针本质是指针常量,指针指向不可修改,

#include<iostream>
#include<string>
using namespace std; 
//常函数和常对象👉const修饰后这样叫成员函数和对象
//常对象只能调用常函数.常对象不能修改class person {
public:void showperson() const //在成员函数后加const,修饰的是this指向,{m_b = 100;}void func() {m_a = 100;}int m_a;mutable int m_b;//特殊变量,即使是在常函数中也可以修改这个值的大小
};void test1() 
{ const person p;//p.m_a = 100;错误p.m_b = 100;//正确,因为这里m_b是一个特殊的变量,可以修改,在常对象下可以修改。//p.func();不允许,不正确,常对象不可以调用普通函数,因为普通函数可以修改属性,而常对象要求不能修改属性
}int main()
{test1();system("pause");return 0;

结语:

希望这篇有关c++对象模型和this指针的博客对大家有所帮助,欢迎大佬们留言o(* ̄▽ ̄*)ブ

一起学习进步!!!

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

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

相关文章

老师翻学生书包违法吗

作为一位老师&#xff0c;我们的职责是教育和引导学生&#xff0c;让他们成为有道德、有知识、有能力的人才。但是&#xff0c;我们有时会遇到一些问题&#xff0c;比如是否可以翻学生的书包。这个问题一直备受争议。 学生的个人隐私权是受到法律保护的。学生享有个人隐私权&a…

【漏洞复现】EduSoho教培系统 任意文件读取

该文章由掌控安全学院——1782814368投稿 【产品介绍】 EduSoho企培系统&#xff0c;基于EduSoho教育云PaaS平台的底层技术打造&#xff0c;专门为快速发展的企业提供一体化企业培训、企业内训组织解决方案&#xff0c;专注人才培养、专注组织建设&#xff0c;帮助企业构建学…

NIO Selector简介

1.Selector和Channel关系 Selector一般称为选择器&#xff0c;也叫多路复用器&#xff0c;NIO的核心组件&#xff0c;用于检查一个或多个Channel的状态是否处于可读、可写的状态。 2.可选择通道 &#xff08;1&#xff09;不是所有的channel都能被selector复用&#xff0c;…

LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

【劳德巴赫 Trace32 高阶系列 5 -- Trace32 JTAG Data.Load 与 Data.Save】

请阅读【Trace32 高阶系列 专栏导读】 文章目录 Data.Load.binaryData.SAVE.BinaryData.Load.binary 用于将二进制文件加载到目标系统的内存中。 Format: Data.LOAD.Binary <file> <address> | <range> [/<option>] <option>: SKIP <of…

基于python+控制台输出的学生信息管理系统

基于python控制台输出的学生信息管理系统 一、系统介绍二、效果展示三、其他系统实现四、获取源码 一、系统介绍 打印功能菜单、添加学生信息、删除学生信息、修改学生信息、显示学生信息、退出系统&#xff0c;并且需要接收用户的输入&#xff0c;在根据输入内容调用相应函数…

理解进程的一些知识准备

1. 认识冯诺依曼体系结构 计算机有很多的体系结构&#xff0c;但到如今&#xff0c;冯诺依曼体系结构变成了主流。 输入设备&#xff1a;话筒、键盘、摄像头、鼠标、磁盘、网卡… 输出设备&#xff1a;声卡、显示器、打印机、显卡、网卡、磁盘… 有的设备既能作为输入设备又能…

多播路由选择

目录 1 多播路由选择 1.1 转发多播数据报时使用三种方法 (1) 洪泛与剪除 RPB 的要点&#xff1a; 1.检查&#xff0c;转发 2.形成以源为根节点的多播转发树 3.剪枝与嫁接 (2) 隧道技术 (tunneling) (3) 基于核心的发现技术 1.2 几种多播路由选择协议 1 多播路由选择 …

docker 构建个人博客网站

1、项目地址 https://gitee.com/hhll/blog-hangliang.git 2、打包docker镜像并上传docker hub 【1】注册docker hub账号https://hub.docker.com/ 【2】在docker hub建对应的仓库 【3】登录docker hub并打包上传前后端镜像 sudo docker login -u xxxx 密码 xxxxxx 后端&am…

视频业务像素、带宽、存储空间计算

一、像素和分辨率 分辨率的单位通常是像素&#xff08;或点&#xff09;&#xff0c;用水平像素数乘以垂直像素数来表示。例如&#xff0c;一个分辨率为1920 x 1080的屏幕有1920个水平像素和1080个垂直像素。 总像素分辨率公式运算 例如 1920 x 10802073600总约200万 500W≈…

Makefile学习

C语言的编译过程 预处理&#xff08;Preprocessing&#xff09; -E是让编译器在预处理之后就退出&#xff0c;不进行后续编译过程&#xff1b;-o是指定输出文件名。 gcc -E hello.c -o hello.i编译&#xff08;Compilation&#xff09; 这里的编译不是指程序从源文件到二进制…

XUbuntu22.04之如何创建、切换多个工作区(二百零九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Android简单支持项目符号的EditText

一、背景及样式效果 因项目需要&#xff0c;需要文本编辑时&#xff0c;支持项目符号&#xff08;无序列表&#xff09;尝试了BulletSpan&#xff0c;但不是很理想&#xff0c;并且考虑到影响老版本回显等因素&#xff0c;最终决定自定义一个BulletEditText。 先看效果&…

异步解耦之RabbitMQ(二)_RabbitMQ架构及交换机

异步解耦之RabbitMQ(一)-CSDN博客 RabbitMQ架构 RabbitMQ是一个基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;协议的消息代理中间件&#xff0c;它通过交换机和队列实现消息的路由和分发。以下是RabbitMQ的架构图&#xff1a; Producer&#xff08;生产…

NAS系统折腾记 – Emby搭建家庭多媒体服务器

Emby简介 Emby是一款优秀的媒体服务器软件&#xff0c;致力于为用户提供丰富的多媒体体验。通过Emby&#xff0c;您可以方便地在家庭内的各种设备上观看您喜爱的电影、电视剧和其他视频内容。而且&#xff0c;Emby还具备强大的媒体管理功能&#xff0c;让您的影视资源井然有序…

Win10系统给文件夹添加备注

在Win10系统中&#xff0c;相信大多用户都没有看到过文件或者是文件夹上有备注信息。下面给大家分享下在Win10系统中给文件夹或文件添加备注的方法。在添加备注之前&#xff0c;首先我们要在需要显示备注的文件夹中显示“备注”标签&#xff0c;否则就算我们给某个文件夹添加了…

BAPI_PRODORD_CREATE-创建生产订单BAPI测试

目录 实现过程和笔记完整程序 实现过程和笔记 完整程序 *&---------------------------------------------------------------------* *& Report z_test_bapi_prodord_create_lhy *&---------------------------------------------------------------------* *&am…

视频编辑场景手绘白板解决方案

传统的视频编辑方式已经不能满足现代企业的多元化需求&#xff0c;美摄科技推出了手绘白板方案&#xff0c;为企业提供了一种全新的直播和视频编辑方式&#xff0c;让手绘内容成为视频的一部分&#xff0c;增强了互动性和视觉效果。 一、手绘白板方案的优势 1、实时手绘&…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(6)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;5&#xff09; 4.1 PCIe总线的基础知识 与PCI总线不同&#xff0c;PCIe总线使用端到端的连接方式&#xff0c;在一条PCIe链路的两端只能各连接一个设备&#xff0c;这两个…

RflySim | 定点位置控制器设计实验四

RflySim| 定点位置控制器设计实验四 01 设计实验 1.建立位置控制通道的传递函数模型 使用MATLAB “ControlSystemDesigner”设计校正控制器,使得加入校正环节后系统速度控制环阶跃响应稳态误差 &#xff0c;相位裕度>75截止频率>2.0rad/s。位置控制环截止频率>1rad/…