【C++】类与对象(引入)
目录
前言
类的引入
类的定义
封装与访问限定符
封装
访问限定符
类的实例化
类的大小
this指针
特性
前言
🎶我们都知道,C语言是面向过程的编程,而C++是面向对象的编程,更多体现在编程的关注点上。
🎶就拿洗衣服来举例吧,对C语言而言,你需要清楚什么时候加水、什么时候手搓,什么时候放洗衣粉。而C++只要将不同的对象如衣服、洗衣机、洗衣粉,进行交互最后便可以得到结果,但过程如何进行,我们并不关心。
🎶这时候,我们便想,要是有一个东西能够像结构体那样可以存储不同的信息,还可以对这些信息进行处理,完成目的的效果就好了。而这个东西就是C++之中的类。
类的引入
🎶我们发现,在C++中,结构体内不仅可以定义变量,也可以定义函数,由此定义了一个类。
但C++更习惯使用一个新的关键字 class 来定义类。
struct ADD
{int add(){return x + y;}int x;int y;
};
类的定义
跟定义结构体是差不多的:
🎶class 为定义类的关键字,ClassName 为类的名字,{ } 中为类的主体,类定义结束时后面分号不能省略。
🎶类体中内容称为类的成员:类中的变量称为类的属性或成员变量,类中的函数称为类的方法或者成员函数。
class className
{// 类体:由成员函数和成员变量组成
};
🎶定义类的方式有两种:
- 声明和定义全部放在类体中,成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
- 成员函数的声明与定义分别存储在不同的文件中,成员函数名前需要加::限定访问的类。
🎶同时为了避免命名出现冲突,成员变量的名字前可以加上一个_,从而避免与成员函数的参数名产生歧义。
class ADD
{
public:void init(int x, int y){_x = x;_y = y;}int add(){return _x + _y;}
private:int _x;int _y;
};
封装与访问限定符
封装
🎶封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
🎶就比如我们使用计算机,只需要使用键盘与鼠标与计算机交互就可以,并不需要知道其主板的具体构造,一些硬件是如何具体运行的。于是计算机就进行了封装,将内部实现细节隐藏起来,同时也是为了保护自身数据不受外部影响,只保留一些接口(鼠标、键盘的接口)供用户使用。
🎶封装本质上是一种管理,让用户更方便使用类。通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。
访问限定符
🎶在类中可以使用访问限定符限定外部对类内部成员的访问,分别是 public 、protected 、private 。
- public 修饰的成员在类外可以直接被访问。
- protected 和 private 修饰的成员在类外不能直接被访问 (此处 protected 和 private 是类似的)。
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
- 如果后面没有访问限定符,作用域就到 } 即类结束。。
- class 的默认访问权限为 private,struct 为 public (因为struct要兼容C)。
🎶值得注意的是,访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
stuct与class的区别
🎶C++需要兼容C语言,所以C++中 struct 可以当成结构体使用。另外C++中 struct 还可以用来定义类。和 class 定义类是一样的,区别是 struct 定义的类默认访问权限是 public ,class 定义的类默认访问权限是 private。
类的实例化
🎶类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类其实并没有分配实际的内存空间来存储它。
🎶用类类型创建对象的过程,称为类的实例化。
🎶同时一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类的成员变量。
🎶类的定义其实就像图纸,而实例化就像用图纸去建造建筑。
int main()
{ADD a;return 0;
}
类的大小
🎶当我们求 ADD 这个类的大小的时候,会发现最后得出的结果是 8 ,若用结构体的思想进行思考,不算函数的结构体的大小也是 8。如此是否说明类中的函数并不算在实例化的范围之中呢?
🎶我们可以设想,若每次实例化都会保存一份代码,相同代码保存多次,便浪费空间。若将公共的函数存放在公共的代码段,需要的时候各个类都可以调用它,无疑是节约了空间,提高利用率。
class ADD
{
public:void init(int x, int y){_x = x;_y = y;}int add(){return _x + _y;}
private:int _x;int _y;
};int main()
{ADD a;cout << sizeof(a) << endl;return 0;
}
既然成员函数,并不在类中存储,由此对类大小的计算便只需要计算其成员变量即可。如此一来便可以使用与结构体相同的对齐方式进行计算。
- 第一个成员在与结构体偏移量为 0 的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8。
- 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
🎶但值得注意的是,对于空类而言,虽然其中并没有任何的成员变量,但是系统还是会为其保留一个字节的空间为其占位,表示其存在。
this指针
🎶如下的代码,我们实体化了两个对象,之后对其进行初始化,函数体中没有关于不同对象的区分,那当 d1 调用 Init 函数时,该函数是如何知道应该设置 d1 对象,而不是设置 d2 对象呢?
class Date
{
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;
};int main()
{Date d1, d2;d1.Init(2023, 2, 22); //初始化d2.Init(2023, 2, 23); //初始化d1.Print();d2.Print();return 0;
}
🎶C++中通过引入 this 指针解决该问题,C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有访问“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要手动传递,由编译器自动完成。若在访问成员变量的时候手动加上this,也可以进行访问,只不过这样就是多此一举,不推荐使用。
void Init(int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}
特性
- this 指针的类型:类的类型 * const ,即成员函数中,不能给 this 指针赋值。只能在“成员函数”的内部使用
- this 指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this 形参。所以对象中不存储 this 指针。
- this 指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
相关文章:

【C++】类与对象(引入)
目录 前言 类的引入 类的定义 封装与访问限定符 封装 访问限定符 类的实例化 类的大小 this指针 特性 前言 🎶我们都知道,C语言是面向过程的编程,而C是面向对象的编程,更多体现在编程的关注点上。 🎶就拿洗…...

Redis 高级数据类型
文章目录一、Bitmaps:属性状态统计二、HyperLogLog:基数统计三、GEO:地理位置信息计算提示:以下是本篇文章正文内容,Redis系列学习将会持续更新 一、Bitmaps:属性状态统计 Bitmaps类型: 统计一…...
Java8 新特性-函数式接口
什么是函数式接口 先来看看传统的创建线程是怎么写的 Thread t1 new Thread(new Runnable() {Overridepublic void run() {System.out.println("t1");} }); t1.start();再来看看使用了函数式接口是怎么写的 Thread t2 new Thread(() -> System.out.println(&…...

这套软件测试试卷能打90分,直接入职字节吧
目录 一.填空 二、 判断题(正确的√,错误的╳)共10分,每小题1分 三、数据库部分:(共15分) 四、设计题。本题共 1 小题,满分 20分 一.填空 1、 系…...

GUI可视化应用开发及Python实现
0 建议学时 4学时,在机房进行 1 开发环境安装及配置 1.1 编程环境 安装PyCharm-community-2019.3.3 安装PyQt5 pip install PyQt5-tools -i https://pypi.douban.com/simple pip3 install PyQt5designer -i https://pypi.douban.com/simple1.2 环境配置 选择“…...

【论文简述】GMFlow: Learning Optical Flow via Global Matching(CVPR 2022)
一、论文简述 1. 第一作者:Haofei Xu 2. 发表年份:2022 3. 发表期刊:CVPR oral 4. 关键词:光流、代价体、Transformers、全局匹配、注意力机制 5. 探索动机:过去几年中具有代表性的光流学习框架的核心估计方式没有…...

【Spark分布式内存计算框架——离线综合实战】5. 业务报表分析
第三章 业务报表分析 一般的系统需要使用报表来展示公司的运营情况、 数据情况等,本章节对数据进行一些常见报表的开发,广告数据业务报表数据流向图如下所示: 具体报表的需求如下: 相关报表开发说明如下: 第一、数据…...

力扣-删除重复的电子邮箱
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:196. 删除重复的电子邮箱二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其…...
git基础
git-note Github Manual | GitHub Cheat Sheet | Visual Git Cheat Sheet 安装配置工具分支创建仓库.gitignore文件同步更改进行更改重做提交术语表 安装 desktop.github.com | git-scm.com 配置工具 对所有本地仓库的用户信息进行配置 对你的commit操作设置关联的用户名…...

postgres 源码解析50 LWLock轻量锁--1
简介 postgres LWLock(轻量级锁)是由SpinLock实现,主要提供对共享存储器的数据结构的互斥访问。LWLock有两种锁模式,一种为排他模式,另一种是共享模式,如果想要读取共享内存中的内容,需要在读取…...
JVM优化常用命令
jps列出正在运行的虚拟机进程jpstop列出线程CPU或内存占用top top -Hp pid //列出pid全部线程jstat监视虚拟机运行状态信息jstat -gc pid 5000 //每隔5s打印gc情况jmapjmap -heap pid //输出jvm内存情况 jmap -histo:live pid | more //查看堆内存中的对象数量和大小 jma…...
按键中断实验
gpio.c#include"gpio.h"//给gpio使能和设置为输入模式void hal_gpio_init(){//使能GPIOF控制器RCC->MP_AHB4ENSETR|(0x1<<5);//通过GPIOF_将pf9/pf7/pf8设置为输入模式 GPIOF->MODER&(~(0x3<<18));GPIOF->MODER&(~(0x3<<14));GPI…...

kubernetes入门介绍,从0到1搭建并使用
Kubernetes是一个容器编排系统,用于自动化应用程序部署、扩展和管理。本指南将介绍Kubernetes的基础知识,包括基本概念、安装部署和基础用法。 基础介绍 Kubernetes是Google开发的开源项目,是一个容器编排系统,可以自动化部署、…...

【C语言进阶】字符串函数与内存函数的学习与模拟实现
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C语言进阶 🎯长路漫漫浩浩,万事皆有期待 文章目录1.字符串处理函数介…...

【JavaEE初阶】第一节.多线程(进阶篇 ) 常见的锁策略、CAS及它的ABA问题
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、常见的锁策略 1.1 乐观锁 vs 悲观锁 1.2 普通的互斥锁 vs 读写锁 1.3 重量级锁 vs 轻量级锁 1.4 自旋锁 vs 挂起等待锁 1.5 公平…...

Linux基础命令-pstree树状显示进程信息
Linux基础命令-uname显示系统内核信息 Linux基础命令-lsof查看进程打开的文件 Linux基础命令-uptime查看系统负载 文章目录 前言 一 命令介绍 二 语法及参数 2.1 使用man查看命令语法 2.2 常用参数 三 参考实例 3.1 以树状图的形式显示所有进程 3.2 以树状图显示进程号…...

keepalived+LVS配置详解
keepalivedLVS配置详解keepalived简介keepalived的应用场景keepalived工作原理VRRP协议核心组件分层工作工作状态LVS简介LVS三种模式NAT模式(网络地址映射)IPTUN模式(IP隧道)DR模式(直接路由)三种模式对比keepalivedLVS配置1.master配置2. keepalived配置文件3 修改keepalived配…...
Unity之C#端使用protobuf
什么是protobuf protobuf全称Protocol Buffers,由Google推出的一种平台、语言无关的数据交互格式,目前使用最广泛的一种数据格式,尤其在网络传输过程中,有很强的安全性,而且数据量比json和xml要小很多。 最主要的是pr…...

C++设计模式(18)——模板方法模式
亦称: Template Method 意图 模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 问题 假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式…...
SQLserver 索引碎片
Oracle 不需要整理碎片,原因? 1. rowid 默认的索引是B-树索引。索引建立在表中的一个或多个列或者是表的表达式上,将列值和行编号一起存储。行编号是唯一标记表中行的伪列。 行编号是物理表中的行数据的内部地址&am…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...

对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...