C++类和对象(上)

目录

1.面向对象和面向过程初步认识

2.类的引入

3.类的定义

3.1类的定义方法

3.2成员变量的命名规则

4.类的访问限定符及封装

4.1类的访问限定符

4.2类的声明和定义分离

4.3封装

5.类的实例化

6.类对象模型

6.1计算类的大小

6.2类对象的存储方式猜测 

7.this指针

7.1this指针的引出

7.2this指针的特点


1.面向对象和面向过程初步认识

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

我们拿洗衣服举例,c语言看的解决问题的过程,这一步解决,下一步需要干什么

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

2.类的引入

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。

C++兼容C struct的用法,但同时也升级成了类:

struct Stack
{//成员变量int* a;int capacity;int top;//成员函数void Init(int n = 4){a = (int*)malloc(sizeof(int) * n);if (nullptr == a){perror("malloc申请空间失败");return;}capacity = n;top = 0;}void Push(int x){a[top++] = x;}
};
int main()
{Stack st1;st1.Init();st1.Push(1);st1.Push(2);st1.Push(3);return 0;
}

上面结构体的定义,在C++中更喜欢用class来代替。

3.类的定义

3.1类的定义方法

class className
{
        // 类体:由成员函数和成员变量组成


};  // 一定要注意后面的分号

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分
号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数

类的两种定义方式:

1.声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
联函数处理。

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名:

 一般情况下,更期望采用第二种方式

3.2成员变量的命名规则

不是很规则的声明

class Date
{void Init(int year, int month, int day){year = year;month = month;day = day;}int year;int month;int day;
};

我们看这段代码是不是非常别扭,因为函数里面初始化的是参数还是成员变量,所以我们C++的习惯就是变量名声明的时候前面加 _(我们这里没有强制规定,看大家习惯)

class Date
{void Init(int year, int month, int day){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};

4.类的访问限定符及封装

4.1类的访问限定符

上面代码调用可能会有问题,这就跟我们接下来的访问限定符有关系(通过访问权限选择性的将其接口提供给外部的用户使用

看两端代码对比,一个是struct,一个是class,struct外面可以调用,class外面不能调用,我们可以得出第一点:

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

2. public修饰的成员在类外可以直接被访问(class默认不能访问,加上public外面就可以访问)

3. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)(struct默认可以访问,加上private外面就访问不到了)

4. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止(因为是class,所以第一段默认是私有,第二段是公有,第三段是私有)

5. 如果后面没有访问限定符,作用域就到 } 即类结束

4.2类的声明和定义分离

我们看 .h 和 .c 文件,函数明明是公有的为什么访问不了,这其实跟公有和私有没关系,这跟我们的类域有关系,可能第一次听类域,其实就跟我们的命名空间域一样的意思,我们在函数前面加上类的域作用限定符就可以解决

4.3封装

封装本质上是一种管理,让用户更方便使用类。比如:对于电脑这样一个复杂的设备,提供给用
户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日
常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如
何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计
算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以
及键盘插孔等,让用户可以与计算机进行交互即可。

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

5.类的实例化

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

1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没
有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个
类,来描述具体学生信息

2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

3.做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设
计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象
才能实际存储数据,占用物理空间

6.类对象模型

6.1计算类的大小

 我们可以看到d1的大小是12,所以这个类里面只是存了成员变量地址,没有存成员函数的地址

6.2类对象的存储方式猜测 

类里面存函数的缺陷:每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一个类创建多个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。那么如何解决呢?

 这个时候会把函数放在一个公共区域(代码段)里面,调用的时候直接去公共区域找函数就可以了,这样就不会有多次调用同样函数的问题了

7.this指针

7.1this指针的引出

我们先定义一个日期类:可以看到打印出来的日期不一样,那问题来了,这两个类都调用了这个函数,为什么打印结果不一样,并且当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

 C++中通过引入this指针解决该问题:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

d1.Print(&d1);//类调用成员函数传了自己的地址
void Print(Date* this)
{cout << _year << "." << _month << "." << _day << endl;
}d2.Print(&d2);
void Print(Date* this)
{cout << _year << "." << _month << "." << _day << endl;
}

7.2this指针的特点

1.不能显示写(上面代码只是演示编译器要怎么做,我们不用传参,也不用接收参数,写了会报错,这是编译器做的

d1.Print(&d1);//类调用成员函数传了自己的地址
void Print(Date* this)
{cout << _year << "." << _month << "." << _day << endl;
}

2.函数内部可以用

d1.Print();//类调用成员函数传了自己的地址
void Print()
{cout << this->_year << "." << this->_month << "." << this->_day << endl;
}

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

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

相关文章

Python初学者学习记录——python基础综合案例:数据可视化——动态柱状图

一、案例效果 通过pyecharts可以实现数据的动态显示&#xff0c;直观的感受1960~2019年世界各国GDP的变化趋势 二、通过Bar构建基础柱状图 反转x轴和y轴 标签数值在右侧 from pyecharts.charts import Bar from pyecharts.options import LabelOpts# 构建柱状图对象 bar Bar()…

基于图像掩膜和深度学习的花生豆分拣(附源码)

目录 项目介绍 图像分类网络构建 处理花生豆图片完成预测 项目介绍 这是一个使用图像掩膜技术和深度学习技术实现的一个花生豆分拣系统 我们有大量的花生豆图片&#xff0c;并以及打好了标签&#xff0c;可以看一下目录结构和几张具体的图片 同时我们也有几张大的图片&…

年假作业day2

1.打印字母图形 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int i,j; char k; for(i1;i<7;i) { for(j1;j<i;j) { printf("%c",_); } for(j0,…

Javaweb之SpringBootWeb案例之异常处理功能的详细解析

3. 异常处理 3.1 当前问题 登录功能和登录校验功能我们都实现了&#xff0c;下面我们学习下今天最后一块技术点&#xff1a;异常处理。首先我们先来看一下系统出现异常之后会发生什么现象&#xff0c;再来介绍异常处理的方案。 我们打开浏览器&#xff0c;访问系统中的新增部…

ARM PAC/BTI/MTE三剑客精讲与实战

一、PAC指针认证精讲与实战 思考 1、什么是栈溢出攻击&#xff1f;什么是代码重用攻击&#xff1f;区别与联系&#xff1f; 2、栈溢出攻击的软&硬件缓解技术有哪些&#xff1f;在TF-A&OPTEE上的应用&#xff1f; 3、什么是ROP攻击&#xff1f;对ROP攻击的缓解技术&…

idea(2023.3.3 ) spring boot热部署,修改热部署延迟时间

1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </dependency>载入依赖 2、设置编辑器 设置两个选项 设置热部署更新延迟时…

LabVIEW热电偶自动校准系统

设计并实现一套基于LabVIEW平台的工业热电偶自动校准系统&#xff0c;通过自动化技术提高校准效率和精度&#xff0c;降低人力成本&#xff0c;确保温度测量的准确性和可靠性。 工业生产过程中&#xff0c;温度的准确测量对产品质量控制至关重要。传统的热电偶校准方式依赖人工…

H12-821_73

73.某台路由器Router LSA如图所示&#xff0c;下列说法中错误的是&#xff1f; A.本路由器的Router ID为10.0.12.1 B.本路由器为DR C.本路由器已建立邻接关系 D.本路由器支持外部路由引入 答案&#xff1a;B 注释&#xff1a; LSA中的链路信息Link ID&#xff0c;Data&#xf…

【大数据】Flink 中的 Slot、Task、Subtask、并行度

Flink 中的 Slot、Task、Subtask、并行度 1.并行度2.Task 与线程3.算子链与 slot 共享资源组4.Task slots 与系统资源5.总结 我们在使用 Flink 时&#xff0c;经常会听到 task&#xff0c;slot&#xff0c;线程 以及 并行度 这几个概念&#xff0c;对于初学者来说&#xff0c;这…

ChatGPT高效提问—prompt常见用法(续篇五)

ChatGPT高效提问—prompt常见用法&#xff08;续篇五&#xff09; 1.1 种子词 ​ 种子词&#xff08;seed word&#xff09;通常指的是在对话中使用的初始提示或关键词&#xff0c;用于引导ChatGPT生成相关回复。种子词可以是一个词、短语或句子&#xff0c;通常与对话的主题…

数据结构——单向链表和双向链表的实现(C语言版)

目录 前言 1. 链表 1.1 链表的概念及结构 1.2 链表的分类 2. 单链表接口实现 2.1 数据结构设计与接口函数声明 2.2 创建结点&#xff0c;打印&#xff0c;查找 2.3 尾插&#xff0c;头插&#xff0c;尾删&#xff0c;头删 2.4 插入或删除 2.4.1在指定位置后 2.4.2在…

LLM大语言模型(六):RAG模式下基于PostgreSQL pgvector插件实现vector向量相似性检索

目录 HightLightMac上安装PostgreSQLDBever图形界面管理端创建DB 使用向量检索vector相似度计算近似近邻索引HNSW近似近邻索引示例 HightLight 使用PostgreSQL来存储和检索vector&#xff0c;在数据规模非庞大的情况下&#xff0c;简单高效。 可以和在线业务共用一套DB&#…

jquery写表格,通过后端传值,并合并单元格

<!DOCTYPE html> <html> <head><title>Table Using jQuery</title><style>#tableWrapper {width: 100%;height: 200px; /* 设置表格容器的高度 */overflow: auto; /* 添加滚动条 */margin-top: -10px; /* 负的外边距值&#xff0c;根据实际…

K8S之标签的介绍和使用

标签 标签定义标签实操1、对Node节点打标签2、对Pod资源打标签查看资源标签删除资源标签 标签定义 标签就是一对 key/value &#xff0c;被关联到对象上。 标签的使用让我们能够表示出对象的特点&#xff0c;比如使用在Pod上&#xff0c;能一眼看出这个Pod是干什么的。也可以用…

Golang的for循环变量和goroutine的陷阱,1.22版本的更新

先来看一段golang 1.22版本之前的for循环的代码 package mainimport "fmt"func main() {done : make(chan bool)values : []string{"chen", "hai", "feng"}for _, v : range values {fmt.Println("start")go func() {fmt.P…

Android:Android Studio安装及环境配置

1开发环境搭建 Android开发需要使用java的jdk环境,所以需要下载JAVA JDK。 1.1安装配置JAVA JDK Java的JDK下载: https://www.oracle.com/technetwork/java/javase/downloads/index.html 配置java的环境变量: JAVA_HOME:java安装路径。 新增环境变量CLASSPATH 在Path环境…

【Linux笔记】动静态库的封装和加载

一、静态库的封装 我们在学习C语言阶段其实就已经知道一个可执行程序的形成过程分为预处理、编译、汇编、链接这四个阶段&#xff0c;而且也知道我们程序中使用的各种库其实是在链接的阶段加载的。 可我们那时候并不知道库是怎么被加载的&#xff0c;或者库是怎么形成的&…

[CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理

文章目录 前言一、所需环境二、实现思路2.1. 定义了LeNet网络模型结构&#xff0c;并训练了20次2.2 以txt格式导出训练结果(模型的各个层权重偏置等参数)2.3 (可选)以pth格式导出训练结果&#xff0c;以方便后期调试2.4 C CUDA要做的事 三、C CUDA具体实现3.1 新建.cu文件并填好…

深度学习在知识图谱问答中的革新与挑战

目录 前言1 背景知识2 基于深度学习改进问句解析模型2.1 谓词匹配2.2 问句解析2.3 逐步生成查询图 3 基于深度学习的端到端模型3.1 端到端框架3.2 简单嵌入技术 4 优势4.1 深入的问题表示4.2 实体关系表示深挖4.3 候选答案排序效果好 5 挑战5.1 依赖大量训练语料5.2 推理类问句…

【Linux系统学习】3.Linux用户和权限

Linux用户和权限 1.认知root用户 1.1 root用户&#xff08;超级管理员&#xff09; 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 在Linux系统中&#xff0c;拥有最大权限的账户名为&#xff1a;root&#xff08;超级管理员&#xff09; 而在前期&#…