【C++基础(五)】类和对象(上)

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++初阶之路⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

类和对象-上

  • 1. 前言
  • 2. 类的引入
  • 3. 类的定义
  • 4. 类的访问限定符
  • 5. 类的实例化
  • 6. 类对象模型
    • 6.1 类对象的存储模式
  • 7. this指针
    • 7.1 this指针的特性
    • 7.2 this指针的用处
  • 8. 总结以及拓展

1. 前言

C语言是面向过程的语言
关注的是过程
而C++是面向对象的语言
关注的是对象

而类和对象就是面向对象的基础!

在这里插入图片描述

C++为了兼容C语言
保留了原先的玩法,并且增加了新的玩法

本章重点:

本篇文章着重讲解类的概念,基本特性
成员函数的性质,和最重要的this指针


2. 类的引入

C语言的结构体功能单一
只能定义成员变量,不能定义函数
而C++中新增了一个玩法:
可以定义成员函数

比如:

struct NEO
{int a;char b[20];void test()//成员函数{cout<<"杭州电子科技大学"<< endl;}void push(char ch,int i)//成员函数{b[i] = ch;}
};int main()
{NEO tmp;tmp.test();//会打印"杭州电子科技大学"tmp.push('a',1);//数组b下标为1的位置会被插入一个字符'a'
}

在C++中,C的结构体就是类
并且C++中更喜欢用class替代struct


3. 类的定义

class className
{// 类体:由成员函数和成员变量组成
};   一定要注意后面的分号

类的定义与结构体类似
只不过将struct换成了class

类成员函数的两种定义方式:

  1. 声明和定义都放在类中:
class people
{char* name;char* sex;int height;int age;void peoinfo()//打印此人的消息{cout<<name<<" "<<sex<<" "<<height<<" "<<age;}
};

这个类的成员函数的声明和定义都在类中
编译器就可能把此函数当作内联处理!
只要是在类中定义的函数都会被看作内联

当然这只是给编译器一建议
具体会不会内当作内联要看代码长度

  1. 类函数声明定义分开

一般说的声明和定义分开是指:
声明放在.h文件,定义放在.cpp文件

.h文件

class people
{char* name;char* sex;int height;int age;void peoinfo()//打印此人的消息
};

.cpp文件(错误实例)

void peoinfo()//打印此人的消息{cout<<name<<" "<<sex<<" "<<height<<" "<<age;}

注意:在另一个文件中,必须要加上类名::
否则系统不知道你是要新定义一个函数
还是要定义已经声明过的函数

正解:

void people::peoinfo()//打印此人的消息{cout<<name<<" "<<sex<<" "<<height<<" "<<age;}

4. 类的访问限定符

首先介绍三个访问限定符:

在这里插入图片描述

访问限定符说明:

  1. public修饰的成员在类外
    可以直接被访问

  2. protected和private修饰的成员
    在类外不能直接被访问

  3. 访问权限作用域:
    从该访问限定符出现的位置开始直到
    下一个访问限定符出现时为止

  4. 如果后面没有访问限定符了
    作用域就一直到类结束

  5. class的默认访问权限为private
    struct为public(因为要兼容C)

举例说明:

class NEO
{
public:void test1(){cout<<"haha";}void test2(){cout<<"hehe";}private:int a;char b[20];double c;
}int main()
{NEO tmp;tmp.test1();//正常运行tmp.a = 10;//运行报错tmp.c = 20;//运行报错return 0;
}

此类中,public和private
之间的成员是共有的,类外可以访问
private到类结束的成员是私有的
类外不能访问!

需要注意的点:

不管成员函数是共有还是私有
也不管成员变量是共有还是私有
成员函数都可以访问到成员变量!


5. 类的实例化

用类类型创建对象的过程,称为类的实例化

在实例化类对象之前,这个类并不占用内存

比如:

class Person
{
public:void printper(){cout<<name;}
private:char* name;
};int main()
{Person.name = "NEO";//编译报错,还没有实例化对象Person p1;return 0;
}

若没有实例化对象p1
这个class类是不会开辟空间的!

class类就像一个设计图纸一样
在按照这个图纸建设房子前
这块区域是没有空间占用的
实例化对象就像按照图纸修房子一样
会占用空间

在这里插入图片描述


6. 类对象模型

怎么计算一个class类的大小?

例如:下面这两个类:

class A
{void PrintA(){cout << a << endl;}int a;char b;
};class B
{int a;char b;
};int main()
{printf("类A的大小: %d\n", sizeof(A));printf("类B的大小: %d\n", sizeof(B));return 0;
}

在这里插入图片描述

结论:

  1. 类中的成员函数不算在类的大小中
  2. 类的大小遵守结构体内存对齐规则
  3. 空类(没有成员变量)的大小是1字节

注:如果你不知道结构体内存对齐规则
请点击:结构体内存对齐规则


6.1 类对象的存储模式

为啥类中的成员函数不占空间?
那函数存储在什么位置?

带着这样的疑惑来看看类的存储模式:

  • 类成员变量存储在实例化对象中
  • 类成员函数存储在公共的代码段

可以用下面这张图来理解:

在这里插入图片描述

对类成员变量的解释:

由于每一个对象中的变量的值可能不同
所以成员变量存储在不同的对象中

对类成员函数的解释:

但是每个对象调用的函数是相同的
为了节省空间,将成员函数从对象中剥离
到公共代码段,不管实例化多少个对象
只要调用成员函数就会去代码段找!


7. this指针

先看以下的日期类:

class Date
{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;     // 年int _month;    // 月int _day;      // 日
};int main()
{Date d1;d1.Init(2023,7,22);//初始化对象return 0;
}

看似Init只有三个参数
看似调用Init时只传了三个参数

但其实还有一个隐藏的指针this!

可以用下图理解this的位置:

在这里插入图片描述

并且在每一个成员变量之前
都有this指针解引用访问它:

在这里插入图片描述


7.1 this指针的特性

基本特性:

  1. this指针的类型:const 类类型 *
    即成员函数中,不能给this指针赋值

  2. 只能在“成员函数”的内部使用

  3. this指针不能我们显示去写
    也不能我们显示去传对象地址

  4. this指针存储在栈区,不存储在对象中

对特性的理解:

不能这样写代码:

class A
{ 
void Init(A* this,int a)
{_a=a;
}int _a;
};int main()
{A a1;a1(&a,10);
}

假如这样写代码,那么函数参数就有三个
系统还是会自动传this指针,会报错


7.2 this指针的用处

假设我们实例化了两个对象
分别是d1和d2

class Date
{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;     // 年int _month;    // 月int _day;      // 日
};int main()
{Date d1;Date d2;d1.Init(2023,7,22);//初始化对象d2.Init(2023,7,23);return 0;
}

已知成员函数是放在公共代码段的
假如没有this指针存在
函数体又没有区别不同对象的手段

那么就会出现一个问题:
对象d1调用函数Init时,函数不知道是
哪一个对象调用了它,就无法区分对象

使用this指针将对象的地址传入函数中
函数体就可以区分不同对象了!


8. 总结以及拓展

本章是类和对象的入门篇
只介绍了类的解基本概念和特性
其中比较重要的是this指针
它还会陪伴我们很久!

基础不牢,地动山摇
类学不会,学C++就受罪

在这里插入图片描述

拓展: C++命名方式

C++又很多习惯的命名方式
这里介绍一个:驼峰法命名

  • 单词和单纯之间首字母大写
  • 函数名,类名首字母大写
  • 变量首字母小写,后面单词首字母大写
  • 成员变量的首字母前加下划线_

举例说明:

class Date
{ 
public:void InitDate(int year, int month, int day)//initialize date{                                          //初始化日期,简写后,I和D要大写_year = year;_month = month;_day = day;}void PrintInfo()//printf information,简写后P和I要大写{cout <<_year<< "-" <<_month << "-"<< _day <<endl;}
private:int _year; //成员变量前面加_int _month;int _day;     
};

🔎 下期预告:类和对象(中) 🔍

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

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

相关文章

【人工智能】深度优先搜索、代价一致搜索、深度有限搜索、迭代深度优先搜索、图搜索

【人工智能】无信息搜索—BFS 、代价一致、DFS、深度受限、迭代深入深度优先、图搜索 什么是搜索 搜索问题是指既不能通过数学建模解决,又没有其他算法可以套用或者非遍历所有情况才能得出正确结果。这时就需要采用搜索算法来解决问题。搜索就是一种通过穷举所有解的状态,来…

iClient3D for CesiumWebGL入门之使用vscode以服务方式运行调试

作者&#xff1a;超图研究院技术支持中心-于丁 iClient3D for Cesium&WebGL入门之使用vscode以服务方式运行调试 相信大家第一次使用SuperMap iClient3D for Cesium或SuperMap iClient3D for WebGL的时候&#xff0c;都遇到过和我一样的事情&#xff1a; 在文件夹中直接打…

Docker网络模式

Docker网络模式 一、Docker网络实现原理二、Docker的网络模式1、host模式1.1 host模式原理1.2 host模式实操 2、Container模式2.1 模式原理 3、none模式4、bridger模式4.1 bridge模式的原理4.2 bridge实操 5、overlay模式6、自定义网络模式6.1 为什么需要自定义网络模式&#x…

03. 自定义镜像 Dockerfile

目录 1、前言 2、构建镜像的方式 2.1、docker commit 2.1.1、先查看下当前的容器 2.1.2、生成该容器镜像 2.1.3、查看镜像列表 2.2、Dockerfile 2.2.1、创建Dockerfile文件 2.2.2、编写Dockerfile文件 2.2.3、构建镜像 2.2.4、使用该镜像生成容器 3、Dockerfile 3…

FTP与HTTP: 哪种协议更适合大文件传输?

随着互联网技术的发展&#xff0c;网络传输已成为了现代社会中不可或缺的一部分。无论是文本、图像、音频、视频等各种类型的数据&#xff0c;相应的传输协议也在不断地发展和更新。FTP&#xff08;File Transfer Protocol&#xff09;和HTTP&#xff08;Hyper Text Transfer P…

【密码学】二、古典密码

古典密码 1.置换密码1.1列置换密码1.2周期置换密码 2.代换密码2.1单表代换密码2.1.1凯撒密码2.1.2仿射密码 2.2多表代换密码2.2.1维吉尼亚密码2.2.2普莱费尔密码 3.轮转密码3.1恩尼格玛密码机Enigma3.1.1Enigma加密3.1.1Enigma解密 4.古典密码的分类5.古典密码的统计分析5.1单表…

【云原生】Prometheus之图形化界面grafana与服务发现部署

前言 上一篇文章中我们介绍了Prometheus的组件&#xff0c;监控作用&#xff0c;部署方式&#xff0c;以及如何通过在客户机安装exporter再添加监控项的操作。但是不免会发现原生的Prometheus的图像化界面对于监控数据并不能其他很好的展示效果。所以本次我们将介绍一款开源非常…

06-Vue基础之事件处理

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

Hive自定义函数

本文章主要分享单行函数UDF&#xff08;一进一出&#xff09; 现在前面大体总结&#xff0c;后边文章详细介绍 自定义函数分为临时函数与永久函数 需要创建Java项目&#xff0c;导入hive依赖 创建类继承 GenericUDF&#xff08;自定义函数的抽象类&#xff09;&#xff08;实现…

HP惠普暗影精灵9笔记本原装出厂Win11系统预装专用OEM系统镜像

暗影9笔记本电脑原厂Windows11系统包 OMEN by HP 16.1英寸游戏本16-wf0000,16-wf0001,16-wf0003,16-wf0004,16-wf0006,16-wf0008,16-wf0009,16-wf0010,16-wf0011,16-wf0012,16-wf0028,16-wf0029,16-wf0007,16-wf0032,16-wf0036,16-wf0043 链接&#xff1a;https://pan.baidu.…

[SQL系列] 从头开始学PostgreSQL 自增 权限和时间

[SQL系列] 从头开始学PostgreSQL 事务 锁 子查询_Edward.W的博客-CSDN博客https://blog.csdn.net/u013379032/article/details/131841058上一篇介绍了事务&#xff0c;锁&#xff0c;子查询 事务有点像是原子操作&#xff0c;需要有完整性&#xff0c;要么全都完成了&#xff…

win11我们无法创建新的分区也找不到现有的分区

U盘重装系统的时候 提示&#xff1a;win11我们无法创建新的分区也找不到现有的分区 ShiftF10 &#xff0c;调出 命令提示符&#xff1b; diskpart list disk select disk 盘编号 clean convert gpt 参考&#xff1a;怎么解决我们无法创建新的分区也找不到现有的分区问题&#x…

STM32F407-- DMA使用

目录 1. DMA结构体 STM32F103&#xff1a; STM32F407&#xff1a; 2. F4系列实现存储器到存储器数据传输 1&#xff09;结构体配置&初始化 2&#xff09;主函数 补充知识点&#xff1a;关于变量存储的位置&#xff0c;关于内部存储器一般存储什么内容 3. F4系列实现…

C++OpenCV(4):图像截取与掩膜操作

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 &#x1f506; OpenCV项目地址及源代码&#xff1a;点击这里 文章目录 图像截取图像掩膜操作 图像截取 ROI操作&#xff0c;指的是&#xff1a;region of interest&#xff0c;感兴趣区域。 我们可以对一张…

Android Studio 修改AVD模拟器文件默认存储路径

AndroidStudio默认的模拟器文件路径为&#xff1a;C:\Users\用户名\.android\avd路径&#xff0c;通常windows系统上&#xff0c;C盘不是太大&#xff0c;而avd文件却不小&#xff0c;通常几个GB&#xff0c;所以有必要将avd路径换到一个非系统盘。 更换方法如下&#xff1a;H…

LocalDateTime、OffsetDateTime、ZonedDateTime之间的关系

什么是LocalDateTime&#xff1f; ISO-8601日历系统中不带时区的日期时间。 该类不存储时区&#xff0c;所以适合日期的描述&#xff0c;比如用于生日、deadline等等。 但是如果没有偏移量/时区等附加信息&#xff0c;一个时间是不能表示时间线上的某一时刻的。 什么是Offset…

20230720在ubuntu22.04系统下载+解密+合并ts切片的步骤(STEP-BY-STEP版本)

20230720在ubuntu22.04系统下载解密合并ts切片的步骤&#xff08;STEP-BY-STEP版本&#xff09; 2023/7/20 23:06 https://app1ce7glfm1187.h5.xiaoeknow.com/v2/course/alive/l_64af6130e4b03e4b54da1681?type2&app_idapp1cE7gLFM1187&pro_idterm_645c69388953e_Nhew…

论文工具——ChatGPT结合PlotNeuralNet快速出神经网络深度学习模型图

文章目录 引言正文PlotNeuralNet安装使用使用python进行编辑使用latex进行编辑 样例利用chatGPT使用chatGPT生成Latex代码利用chatGPT生成对应的python代码 总结引用 引言 介绍如何安装PlotNeuralNet工具&#xff0c;并结合chatGPT减少学习成本&#xff0c;快速出图。将按照软…

前端Web实战:从零打造一个类Visio的流程图拓扑图绘图工具

前言 大家好&#xff0c;本系列从Web前端实战的角度&#xff0c;给大家分享介绍如何从零打造一个自己专属的绘图工具&#xff0c;实现流程图、拓扑图、脑图等类Visio的绘图工具。 你将收获 免费好用、专属自己的绘图工具前端项目实战学习如何从0搭建一个前端项目等基础框架项…

java学习(二):反射

系列文章目录 https://editor.csdn.net/md/?articleId131757340 文章目录 系列文章目录参考【1】注解1. 什么是注解2. 内置注解3. 元注解4.自定义注解 【2】反射--基本概念一、反射的基本概念1. 为什么要用反射&#xff1f;2. 什么是反射&#xff1f;3. 用和不用反射的区别&a…