【C++打怪之路Lv3】-- 类和对象(上)

🌈 个人主页:白子寰
🔥 分类专栏:C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~) 

 

目录

面向对象和面向过程的认识

类的引入(以下以Stack为例)

 类的介绍

类的第一种定义方法

类的第二种定义方法:类的作用域

 成员变量命名规则

建议①

建议②

类的访问限定符

访问限定符的介绍

 封装

类的实例化

概念

 理解类的实例化(含图片和代码)

 类对象模型

计算类对象大小

结构体内存对齐

 this指针

this指针的引入

 this指针的特性

C语言和C++实现Stack的对比

C语言

C++ 


 

面向对象和面向过程的认识

C语言面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

那什么是过程?什么是对象呢?

我们在生活中举例子:比如我要去烧一壶开水

对象:我,热水壶,水,排插/插座,热水壶托盘

过程:把水接到水壶里 --> 关闭水壶盖 --> 把热水壶放到托盘中 --> 连接好插排/插座 --> 按下热水壶开关 --> 静等几分钟 -->一壶水烧开了



 

类的引入(以下以Stack为例)

在C语言中,我们学过结构体,但在C语言的结构体当中,只能由成员变量组成,回顾一下怎么用C语言实现(Stack)栈的呢?


然而在C++当中,结构体里不仅可以定义成员变量,还可以定义成员函数,那就是“类” 


 类的介绍

在C++当中,喜欢把struct写成class(类),什么是类?

class ClassName
{//由 成员变量 和 成员函数 来组成
};

注:1、class和struct相似,   2、ClassName是类的名称,

       3、名称后需跟中括号{},4、右中括号后还有分号 ( ; )


 那么在C++当中关于栈的类是怎么定义的呢?

类的第一种定义方法

在class(类)中声明和定义成员变量和成员函数(可以在class中具体实现成员函数)

注:(成员函数如果放在类体中,编译器可能会当成内联函数处理)

(关于访问权限我们在后续中会讲到,这里先做铺垫)


 

类的第二种定义方法:类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。

在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

在class(类)中定义成员变量和定义成员函数,

在.cpp文件中声明成员函数  (也就是通过类和作用域限定符指定实现Stack类中的某个函数)


 成员变量命名规则

建议①

成员变量用 _year 表示

建议②

成员变量用 前缀(m_year) 或者 后缀(例如:year_m)来表示


类的访问限定符

访问限定符的介绍

C++实现封装(文章下面会讲到)的方式:

用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

访问限定符包括:public(公有),protected(保护),private(私有)

注: 1、public修饰的成员在类外是直接可以访问的

        2、private修饰的成员在类外不能直接被访问(protect和private是类似的)

        3、访问权限作用域从访问权限开始到下一个访问权限出现结束

        4、 如访问没有限定符,那就到 } 结束

        5、class默认访问权限是private,struct默认访问权限是public(struct兼容C语言)



 

 封装

面向对象的三大特性:封装、继承、多态

在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来               和对象进行交互。

封装本质上是一种管理,让用户更方便使用类

就像上面说的 面向对象和面向过程的认识 一样

烧一壶开水,我们只需关心把水装进水壶,再按下按钮就可以了

                              并不关心开水是怎么烧开的,它的内部用什么装置和线路组成的(封装)

用户只需要与厂家提供的按钮,热水壶等显而易见直接实现的外部装置之间进行交互

在C++语言中实现封装,

可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。



 

类的实例化

概念

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

类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,

定义出一个类并没有分配实际的内存空间来存储它

打个比方:

类实例化出对象就像现实中使用建筑设计图建造出房子,

类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在

同样类也只是一个设计实例化出的对象才能实际存储数据,占用物理空间

类  和  对象 是 一对多的关系

一个类可以有多个对象,比方类是设计图,对象是通过设计建出来的房子,

一个设计图可以设计建造出多个类似的房子


 

 理解类的实例化(含图片和代码)

 举例:Data日期类

class Data
{
public:void Init(int yaer, int month, int day){m_year = yaer;m_month = month;m_day = day;}private:int m_year; //年int m_month;//月int m_day;  //日
};int main()
{Data s1;		//定义(实例化)对象Data s2;		//定义(实例化)对象s1.Init(2024, 4, 25);s1.Init(2024, 4, 25);Data s3;		//定义(实例化)对象Data s4;		//定义(实例化)对象s1._yaer++;		//成员变量的权限为privates2._yaer++;return 0;
}



 

 类对象模型

计算类对象大小

(看下面Data类,类A、B、C)

class Data
{
public:void Init(int yaer, int month, int day){_year = yaer;_month = month;_day = day;}private:int _year;int _month;int _day;
};class A
{};class B
{
private:int a;char b;
};class C
{
public:void D(){}
};int main()
{Data d1;cout << sizeof(d1) << endl;cout << sizeof(A) << endl;cout << sizeof(B) << endl;cout << sizeof(C) << endl;
}

 怎么计算类对象的大小呢?(Data类,类A、B、C)它们的大小分别为多少?

一个类的大小,实际就是该类中”成员变量”之和

当然要注意内存对齐注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

控制台输出显示 

 


 

结构体内存对齐

详细讲解请看该篇文章:结构体超详细总结(含结构体内存对齐)icon-default.png?t=N7T8http://t.csdnimg.cn/YIAAr 


 


 this指针

this指针的引入

看一下前面提到的Data(日期类)

class Data
{
public:void Init(int yaer, int month, int day){_year = yaer;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Data d1;Data d2;d1.Init(2024, 4, 27);d2.Init(2023, 4, 27);d1.Print();d2.Print();return 0;
}

 现有这样一个问题,

当d1调用Init成员函数时,该函数如何知道应该设置d1对象而不是设置d2对象呢?

C++中通过引入this指针解决该问题,

即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象)

函数体中所有“成员变量”的操作,都是通过该指针去访问

只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成

 this指针的特性

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

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

3、this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针

4、this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传

递,不需要用户传递


 

 d1和d2都调用该成员函数,但结果却不同的原因是

void Print() 函数再编译器编译是 void Print(Data* const this),有一个隐藏参数this指针

d1调用函数时,是这样子来访问的:

&d1->_year、&d1->_month、&d1->_day,

此时this指针就是d1的指针,&d1是实参,Data* this是形参(局部变量),访问的是d1的对象_year,_monh,_day

 



 

C语言和C++实现Stack的对比

C语言

共性

1、每个函数的第一个参数都是Stack*

2、函数中必须要对第一个参数检测,因为该参数可能会为NULL函数中都是通过Stack*参数操作栈的

3、调用时必须传递Stack结构体变量的地址

结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,即数据和操作数据的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出错。


C++ 

C++中通过类可以将数据 以及 操作数据的方法进行完美结合

通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。

而且每个方法不需要传递Stack*的参数了,编译器编译之后该参数会自动还原,

即C++中 Stack * 参数是编译器维护的,C语言中需用用户自己维护。



 

 

 ***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

“欲买桂花同载酒,终不似,少年游”。

我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!! 
好了划走吧。

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

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

相关文章

避坑:我找到了Hexo安知鱼的音乐馆配置(目前好像还没有教程)

我发现安知鱼的音乐配置根本就找不到说明就无奈自己逆向了一下&#xff0c;找到了配置文件&#xff0c;写在博客里记录一下也算是给大家避坑 我的版本是1.6.12&#xff0c;如果你和我的不一样可以看后面 配置文件就是Blog\themes\anzhiyu\source\js\utils.js 打开该文件&…

开发环境搭建:Windows 桌面应用程序

文章目录 前言1、开发环境准备2、Hello World !3、发布总结 前言 操作系统&#xff1a;Windows 10 企业版 LTSC 1809 IDE&#xff1a;Microsoft Visual Studio 2022 Community 说明&#xff1a;Windows 10 企业版 LTSC 1809 不支持 .NET 4.8.1 详情请查看官方说明文档 1、开发…

【华为OD机试】手机App防沉迷系统【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 智能手机方便了我们生活的同时,也侵占了我们不少的时间。 “手机App防沉迷系统”能够让我们每天合理地规划手机App使用时间,在正确的时间做正确的事。 它的大概原理是这样的: 在一天24小…

The Log-Structured Merge-Tree (LSM-Tree) 论文阅读笔记

原论文&#xff1a;The Log-Structured Merge-Tree (LSM-Tree) LSM-Tree的简介和关键技术要点 LSM-Tree&#xff08;Log-Structured Merge-Tree&#xff09;是一种为高吞吐量读写操作优化的数据结构&#xff0c;特别适用于写入密集型的应用场景。它由Patrick O’Neil等人开发…

基于streamlit快速部署机器学习项目(Public URL)

基于streamlit的AIGC项目前端展示 1.Streamlit 简介与入门1.1 安装 Streamlit1.2 开发Streamlit应用程序1.3 启动并运行1.3.1 本地运行1.3.2 部署 现在LLM技术发展迅速&#xff0c;很多人在学习的时候&#xff0c;都想展示效果&#xff0c;并且想部署在服务器上&#xff0c;但是…

SpringBoot的核心内容之自动装配

不面试不知道&#xff0c;现在面试的问题真的是五花八门的&#xff0c;最近就有读者说&#xff0c;在面试的过程中&#xff0c;面试官还提到了关于最初版本的 Spring 还有 SpringMVC 以及现在的 SpringBoot 中的一些相关问题&#xff0c;比如他提到了这个 SpringBoot 的自动装配…

【人工智能基础】线性回归实验分析

实验使用到的库&#xff1a;numpy、matplotlib、scikit-learn 实验使用的开发环境&#xff1a;anaconda、jupyter 一、线性回归 线性回归就是使用一个线性函数&#xff08;多项式回归可以是曲线&#xff09;去拟合给定的训练集&#xff0c;测试时&#xff0c;对输入的x值&#…

Selenium一本通

Selenium中文官方文档 从一个测试脚本说起 from selenium import webdriver #引入selenium webdriver模块 driver webdriver.Firefox() #初始化Firefox浏览器的webdriver对象&#xff0c;启动浏览器 driver.get("http://cn.bing.com/") #跳转到对应页面 assert Bi…

Jammy@Jetson Orin - Tensorflow Keras Get Started: Concept

JammyJetson Orin - Tensorflow & Keras Get Started: Concept 1. 源由2. 模型2.1 推理流程2.1.1 获取图像2.1.2 算法识别2.1.3 判断决策 2.2 理想情况2.2.1 多因素输入2.2.2 理想识别概率 2.3 学习过程2.3.1 标记训练集2.3.2 损失函数2.3.3 训练网络2.3.4 渐进方法 3. 总…

jvm(JVM快速入门、stack栈、堆、GC垃圾回收、Arthas)

文章目录 1. JVM快速入门1.1. 结构图1.2. 类加载器ClassLoader1.3. 执行引擎Execution Engine1.4. 本地接口Native Interface1.5. Native Method Stack1.6. PC寄存器(程序计数器)1.7. Method Area方法区 2. stack栈3. 堆3.1. 堆体系概述3.1.1. 新生区3.1.2. 老年代3.1.3. 永久代…

Python 打包:pyinstaller

目录 为什么选择它用法详解所有命令常规-h-v、 --version--distpath DIR--workpath Workpath-y、 --noconfirm--upx dir upx_dir Upx-a、 --ascii--clean--log-level LEVEL 生成内容-D、 --onedir-F、 --onefile--specpath DIR-n NAME&#xff0c;--NAME NAME-w 执行程序 为什么…

python基础知识点(蓝桥杯python科目个人复习计划66)

今日复习内容&#xff1a;算法双周赛 第一题&#xff1a;疯狂星期六 题目描述&#xff1a; 麦肯鸡是一家名声在外的汉堡店&#xff0c;他们最近推出了一份名为vivo50的套餐&#xff0c;只需要在门口大声喊出vivo50&#xff0c;就可以获得这个套餐。 现在&#xff0c;请你打…

【VUE】解决 Element UI 中 el-tab 切换时 ECharts 渲染宽度问题

解决 Element UI 中 el-tab 切换时 ECharts 渲染宽度问题 在使用 Element UI 的 el-tabs 组件时&#xff0c;我们常常会遇到一个问题&#xff1a;当 ECharts 图表被放在非当前激活的 Tab 内时&#xff0c;图表无法正确渲染其宽度和高度。由于在 Tab 未激活状态下&#xff0c;图…

[Java、Android面试]_21_Dalvik VM与JVM的区别

欢迎查看合集&#xff1a; Java、Android面试高频系列文章合集 文章目录 1. 结构2. 编译3. 运行环境4. Dalvik进程管理 Dalvik是android系统中的虚拟机&#xff0c;JVM是java虚拟机。 Dalvik VM可以支持将已转化为.dex文件格式的java应用程序的运行&#xff0c;.dex是专为Dalvi…

Windows程序设计 - 字符与字符串处理

目录 字符编码的问题 ANSI Vs Unicode 函数版本区分 C RunTime库 老生常谈的ASCII和UNICODE支持性 安全字符串函数 推介的字符和字符串处理的方式 ASCII与UNICODE互转 Reference 字符编码的问题 对于一些像我这样的初学者&#xff1a;很喜欢认为字符串的处理就是将字…

了解ASK模块STX883Pro和超外接收模块SRX883Pro的独特之处 STX883Pro模块具有以下特点:

高发射功率&#xff1a;STX883Pro具有较高的发射功率&#xff0c;可实现长距离的信号传输&#xff0c;适用于需要覆盖广泛区域的应用场景。 高频率稳定性&#xff1a;具备稳定的频率输出&#xff0c;确保信号传输的可靠性和一致性&#xff0c;避免频率漂移导致的通信故障。 大…

Ubuntu 18.04 安装 CMake Ceres-Solver 记录

1. 安装 CMake-3.22.1 不可卸载原有版本 CMake&#xff08;防止 ROS 出现问题&#xff09;&#xff0c;只需建立软链接即可 1. 源码下载并解压wget https://cmake.org/files/v3.22/cmake-3.22.1.tar.gz tar -xvzf cmake-3.22.1.tar.gz2. 移动到合适目录sudo mv cmake-3.22.1 /u…

C++ | Leetcode C++题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution { public:void rotate(vector<vector<int>>& matrix) {int n matrix.size();// 水平翻转for (int i 0; i < n / 2; i) {for (int j 0; j < n; j) {swap(matrix[i][j], matrix[n - i - 1][j]);}}//…

Thread方法具体解析

对于run方法 如果该线程是使用单独的 Runnable run 对象构造的&#xff0c;则调用该 Runnable 对象的 run 方法&#xff1b;否则&#xff0c;此方法不执行任何操作并返回。 对于start方法 导致该线程开始执行&#xff1b; Java虚拟机调用该线程的run方法。 这里介绍一个快捷键…

Java Spring 中构造函数注入和Setter注入的优缺点

在使用Java Spring框架进行依赖注入时&#xff0c;我们常常会遇到构造函数注入和Setter注入两种方式。这两种方式各有优缺点&#xff0c;本文将对它们进行比较和分析&#xff0c;帮助开发者在实际项目中做出合适的选择。 构造函数注入 构造函数注入是通过在类的构造函数中传入…