初次认识C++类

news2024/11/29 2:29:45

目录

前言:

面向过程和面向对象的区别:

C语言:

C++:         

类的引入:

类的定义:

类的权限:

类的作用域: 

类的实例化:

类的大小计算:

空类或则只有成员函数的类:

 this指针:


前言:

        通过学习我们总是能够听见有人说C语言是面向过程编程,而C++是面向对象编程。但是对于我们接触C++不久的同学或则是对C语言的理解不够深刻的同学来说,对于这两个区别并不大,包括我来说也是如此,因为我们本身对于代码量的积累,项目的实践太少了,不过通过下面的讲解,估计可以让你在脑海中形成一种思维来区别它们。

面向过程和面向对象的区别:

        我们分别利用C和C++的方式对洗衣服这一件事情进行描述。

C语言:

  

        上图描述了我们用C语言完成洗衣服这一过程的描述,对于C语言来说,每一步要做什么都是需要我们自己考虑清楚,并且它们之间的顺序不能改变,否则整个过程就会出现问题,导致程序BUG,当然不能考虑删除部分代码程序莫名能跑的奇怪情况。

C++:         

         对于C++来说,我们实现洗衣服这一个过程一共需要4个对象:人,衣服,洗衣粉,洗衣机,然后这4个对象之间相互交互,最终实现问题,对于对象谁先出现谁后出现,它们是如何完成的这一过程我们不需要知道。

        上述讲解有些抽象,我这里用人话将就是说,C++将一个对象描述起来了,就像是C语言的结构体一样,描述一个学生,需要它的名字,学号等等信息,不过C++比起C语言来说多了一个新的功能,那就是允许在这个结构当中添加成员函数,这就是面向对象最关键的部分,这意味着这一个对象实现之后,我们只需要通过它提供的函数接口就能知道这个对象能够实现哪一些功能,然后通过我们自己的发挥与其它对象提供的函数接口进行交互,从而达到最终的目的。

类的引入:

        C语言的结构体当中只能定义变量,但是你创建一个cpp文件之后,你会惊奇的发现,结构体当中还能够定义函数了。

struct test
{
	void test1()
	{
		cout << "hello world" << endl;
	}

	int a;
	int b;
};

类的定义:

class test
{

};

        虽然在C++中可以用结构体来写类,但是对于C++来说,我们更习惯于用class来代替,结构体和类对于当前的我们来说是没有区别的,但是是有一点需要注意,那就是它们的默认访问权限不同,结构体中是公有权限,而类中是私有权限。

类的权限:

        类的权限有三种,public(公有)、protected(保护)、private(私有),通过在类里面写下这几个关键字,可以更改成员权限,权限的作用域从关键字到下一个关键字或则结束。

        公有权限表示类内部能够访问,类外部也能够访问、子类也能够访问。

        保护权限表示类内部能够访问,类外部不能够访问、子类能够访问。

        私有权限表示类内部能够访问、类外部不能访问、子类不能访问。

        不过现在我们还没有学习关于继承相关的知识,所以说保护权限和私有权限对于我们来说是一样的。

class Stu
{
//公有权限:(外部能够访问,内部能够访问)
public:
	//声明(在类外部可以定义)
	void set(int num, int score);

	void change(int num, int score);
	//直接在函数内部
	void print()
	{
		cout << _num << endl;
		cout << _score << endl;
	}
	void print2()
	{
		cout << "hello world" << endl;
	}
	int a;
//保护权限:(外部不能访问,子类可以访问,内部可以访问)
protected:

//私有权限:(只有内部可以访问,其它都不能访问)
private:
	//在类里的变量名添加一个下划线是为了避免与函数的参数相同
	//因为变量查找是从最近作用域到外逐渐查找的,避免之后函数
	//内部访问不到我们的类信息
	int _num;
	int _score;
};

类的作用域: 

        类的实现实际就是实现了一个新的作用域,它里面所有的成员都在类的作用域当中,当类外定义内部成员时需要用::作用域操作符指明作用域。

class Person
{
public:
    void PrintPersonInfo();
private:
    char _name[20];
    char _gender[3];
    int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
cout << _name << " "<< _gender << " " << _age << endl;
}

类的实例化:

        用类创建一个对象的过程就被称为类的实例化,判断一个变量是声明还是实例化只需要通过判断编辑器是否实际分配了内存空间。

//类的声明
class test
{
public:
	void print()
	{
		cout << "hello world" << endl;
	}
};
void test2();

int main()
{
	//类的实例化
	test t1;
}

        可以理解为我们将一个类描述了出来,但是没有实际分配空间给他,就被称为声明,我们通过这个类去定义一个变量,编辑器就会为这个变量分配空间。

类的大小计算:

        类的大小计算和结构体是一模一样对齐方式,在32位机器下,下一个变量的字节加上前面的字节数超过了8个字节就会另外开辟一个新的8个字节存储该变量,vs下是8个字节,根据实际的编辑器来考虑,计算完成之后的对齐数必须是最大变量类型的整数倍或则是默认对其数的整数倍,谁小就是谁。嵌套了结构体,嵌套的结构体对齐到字节的最大对齐数的整数倍。

空类或则只有成员函数的类:

        当一个类里面什么都没有时,它的大小也不会是0,因为通过我们对实例化的理解,如果不分配一个空间给他那就不算时实例化,如果字节为0,到底算不算是实例化呢,所以编辑器会主动为我们的空类分配1字节的空间,作为一个占位符,没有其它意义,有变量的时候编辑器不会给。

        当类里面只有成员函数,它的大小还是1,有朋友会想,函数的地址在32位编辑器下不是4个字节吗,为什么会不占用内存?事实上,并不是函数不占用内存,而是函数的空间被放到了一个名为代码段的存放区域。

        原因也是很容易想到的,如果我们实例化一个空间就对这个函数分配一个空间,那么势必会导致空间的浪费,因为这些函数实现了一模一样的功能,它们又不分辨里面的数据,所以才会将其移动出去。

struct test
{
	void test1()
	{
		cout << "hello world" << endl;
	}
};

class Stu
{
public:
	void print()
	{
		cout << _num << endl;
		cout << _score << endl;
	}
private:
	int _num;
	int _score;
	int a;
};

 

 this指针:

        想必大家在学习类的时候一定是听过一个东西this,他作用于对象里面,大家也没有写它,但是就是在非静态函数当中能够使用它,那么这是为什么呢?

void Stu::change(int num, int score)
{
	//函数是如何分辨_num和_score的所属?
	_num = num;
	_score = score;
}

Stu s1;
//表面上我们的传参
s1.change(1, 2);
//实际上编辑器的传参
s1.change(&s1, 1, 2);

        通过上述代码,我们看到了change函数只有两个参数,我们传参也是传了2个,但是编辑器为我们悄悄做了一件事情,那就是将我们的传参中添加一个&s1,得到了s1的地址,这样我们就能够使用s1里面的成员了。

        但是如果传入三个参数又与我们的函数对应不上,所以编辑器为我们将函数改了。

void Stu::change(Stu* this, int num, int score)
{
	//正常写法当中写上this和不写是一样的,我们不写编辑器会为我们写
	this->_num = num;
	this->_score = score;
}

        这一过程我们自己是不能写的,写了就错,我只需要知道编辑器为我们做了这一件事情就行。

        既然编辑器会传地址过去,那我们传一个空指针能行吗?

        答案是能行,并且我们还能够调用部分函数。能调用函数的原因大伙看了上面类的大小应该是能够理解的,因为类里面的函数是存储在代码段当中的,所以调用它的函数不算是空指针解引用,但如果我们使用了他里面的成员变量,这就不对了,因为成员变量在类里面分配了空间,使用它就是对空指针解引用,导致错误。


        以上就是咱们初次认识类的内容啦。

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

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

相关文章

急速肝了一波ChatGPT,听说阿里面试题都没问题~

目录前言注册步骤&#xff1a;最后总结前言 互联网圈子里面ChatGPT现在实在是太火了&#xff0c;但是你还没用过&#xff1f;我只能说你OUT了&#xff0c;ChatGPT是什么呢&#xff1f; 由人工智能实验室OpenAI发布的对话式大型语言模型ChatGPT引爆中文互联网。它可以与人类轻松…

2022年ts学习记录

以下记录的是&#xff0c;我在学习中的一些学习笔记&#xff0c;这篇笔记是自己学习的学习大杂烩&#xff0c;主要用于记录&#xff0c;方便查找一、TS 是什么 &#xff1f;##1、简介TS&#xff1a;是TypeScript的简称&#xff0c;是一种由微软开发的自由和开源的编程语言。ts …

朗润外盘国际期货:SC原油市场情绪回暖领涨期市

今日值得回溯的三个行情&#xff1a;①SC原油主力合约今日收高4.23%&#xff0c;研报建议仍以震荡行情对待&#xff1f;②沪锡主力合约收涨3.20%&#xff0c;现在做多合适吗&#xff1f;③鸡蛋主力合约收跌1.32%&#xff0c;研报称这只是小幅回调。 【今日期市盘面概况】 整体…

深度学习 Day25——使用Pytorch实现彩色图片识别

深度学习 Day25——使用Pytorch实现彩色图片识别 文章目录深度学习 Day25——使用Pytorch实现彩色图片识别一、前言二、我的环境三、前期工作1、导入依赖项和设置GPU2、下载数据3、加载数据4、数据可视化四、构建CNN网络结构1、函数介绍2、构建CNN并打印模型3、可视化模型结构五…

Docker安装EalasticSearch、Kibana,安装Elasticvue插件

使用Docker快速安装部署ES和Kibana的前提&#xff1a;首先需要确保已经安装了Docker环境。 如果没有安装Docker的话&#xff0c;先在Linux上安装Docker。 有了Docker环境后&#xff0c;就可以使用Docker安装部署ES和Kibana了 一、安装ES 1、拉取EalasticSearch镜像 docker p…

SpringIOC之创建Bean的核心方法doGetBean

概述面向资源&#xff08;XML、Properties&#xff09;、面向注解定义的 Bean 是如何被解析成 BeanDefinition&#xff08;Bean 的“前身”&#xff09;&#xff0c;并保存至 BeanDefinitionRegistry 注册中心里面&#xff0c;实际也是通过 ConcurrentHashMap 进行保存。Spring…

强缓存与协商缓存

Ⅰ、http缓存 HTTP 缓存策略 分为 > 「强制缓存」 和 「协商缓存」 为什么需要 HTTP 缓存 呢 ? &#x1f447; 直接使用缓存速度 >> 远比重新请求快 缓存对象有那些呢 &#xff1f;&#x1f447; 「图片」 「JS文件」 「CSS文件」 等等 文章目录Ⅰ、http缓存Ⅱ…

Hi3559av100平台8路1080P/720P输入配置流程梳理

平台&#xff1a; hi3559av100 硬件连接&#xff1a; 8路YUV422 -> 4路 2lane MIPI -> hi3559av100 最终效果&#xff1a; 经过处理后&#xff0c;后端可以实现8路独立视频流处理&#xff1b; 可以自由和后级VPSS/VENC/VO等模块进行绑定和处理 前言&#xff1a; &…

Spring-整合Mybatis

Spring-整合Mybatis 6&#xff0c;Spring整合 6.1 Spring整合Mybatis思路分析 6.1.1 环境准备 在准备环境的过程中&#xff0c;我们也来回顾下Mybatis开发的相关内容: 步骤1:准备数据库表 Mybatis是来操作数据库表&#xff0c;所以先创建一个数据库及表 create database…

IDEA设置默认JDK、Maven版本问题汇总

遇到的问题&#xff1a;使用IDEA导入一个Maven多模块项目遇到关于JDK和Maven版本相关的问题&#xff0c;这里记录一下解决办法。如何修改当前项目JDK和Maven的版本&#xff1f;修改当前项目对应Maven版本&#xff1a;File -> Setting -> 搜索Maven修改JDK版本&#xff0c…

图像处理--OpenCV学习笔记

内容简介 OpenCV是应用广泛的开源图像处理库&#xff0c;包括基本的图像处理方法&#xff1a;几何变换&#xff0c;形态学变换&#xff0c;图像平滑&#xff0c;直方图操作&#xff0c;模板匹配&#xff0c;霍夫变换&#xff1b;特征提取和描述方法&#xff1a;理解角点特征&a…

Linux驱动开发基础__工作队列

目录 1 引入 2 内核函数 2.1 定义work 2.2 使用 work&#xff1a;schedule_work 2.3 其他函数 3 代码 3.1 gpio_key_drv.c 3.2 button_test.c 4 内部机制 4.1 Linux 2.x 的工作队列创建过程 4.2 Linux 4.x 的工作队列创建过程 1 引入 前面讲的定时器、下半部 task…

ASEMI整流模块MDQ100-16的优点是什么?

编辑-Z ASEMI整流模块MDQ100-16参数&#xff1a; 型号&#xff1a;MDQ100-16 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;1600V 最大RMS电桥输入电压&#xff08;VRMS&#xff09;&#xff1a;1700V 最大平均正向整流输出电流&#xff08;IF&#xff0…

【内网安全】——Linux提权姿势

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 一切为了她座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日emo&#xff1a; 希望你在新的一年也能更好&#xff0c;不惧流言蜚语&…

Django drf使用Django自带的用户系统的注册功能实现

在写登录功能的时候看着网上的视频学着做,然后看了源码的时候发现了一些有意思的功能,因此写这一篇笔记分享给大家. 1.阅读Django自带用户系统源码 1.1 阅读User类源码 系统自带的用户系统的models文件的位置\site-packages\django\contrib\auth\models.py,打开这个文件发现…

python爬虫--re模块简介

Python re正则表达式模块用法详解 前面章节介绍了一些系统自带的工具函数&#xff0c;如 id()、max()。这些函数在 Python 启动时会自动加载进来&#xff0c;不需要我们做任何事情。但并不是所有的模块都是自动加载进来的&#xff0c;因为有些模块不常用&#xff0c;它们只是在…

记录一次web server服务器编程过程中的bug

按照书上和视频中的代码比对没有问题&#xff0c;但是read函数输出不了连接的http请求&#xff0c;不断编译了好几遍还是不行&#xff0c;确定是端口的问题 首先&#xff0c;在云服务器中安全规则里已经允许了相应端口&#xff0c;如果还不可以&#xff0c;可以查看一下系统防火…

MyBatis 入门教程详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

配电室辅控项目无线组网远程在线控制系统解决方案

方案背景 配电室是电力系统末端配电网中传输、分配电能的主要电气设备场所&#xff0c;是城市配电网系统的重要组成部分&#xff0c;起到保护、计量、分配电能的作用。 长期以来&#xff0c;配电室管理工作一直是供电系统运行管理的薄弱环节之一。一些配电室开关跳闸、危险气…

【C++提高编程】set/ multiset 容器详解(附测试用例与结果图)

目录1 set/ multiset 容器1.1 set基本概念1.2 set构造和赋值1.3 set大小和交换1.4 set插入和删除1.5 set查找和统计1.6 set和multiset区别1.7 set容器排序1 set/ multiset 容器 1.1 set基本概念 简介&#xff1a; 所有元素都会在插入时自动被排序 本质&#xff1a; set/mu…