详说 类和对象

news2024/11/14 13:50:00

类怎么定义

类是什么呢?类就是我们上篇文说的命名空间,单独创建一个域,自己有自己的生命空间,那么类怎么定义呢?C++规定,假设 stack就是他的类名,那么前面要加个class,换行之后就是他的类的内容,类里面有定义的变量和我们自己的成员函数,要注意的是,C++兼容C语言,所以也是可以用struct代替class成为关键词的,唯一的区别就是,struct默认变量和成员函数是公有的,而class默认是私有的,为了更好理解,我们贴个代码。

上图就很好的展现了struct 和 class的区别。 

访问限定符

我们上面说到类里面是有公有和私有之分的,那么我们怎么区分呢?C++规定了三个访问限定符,分别是public,private,protected。我们暂时只讲前两个,protected我们放到以后再讲。至于怎么用,我们贴个代码。

类域

我们建立了类这个东西,都知道,他的作用域是独立的,所以我们在这个类外面使用类时,我们必须使用::这个作用域操作符去指明是哪个类里面的。

还有一条注意事项是,我们成员函数声明和定义分离的时候,如果定义在类的外面,那么一定要使用::这个操作符,当编译器在全局域找不到这个函数的时候,编译器就知道去哪里找这个函数了。

实例化

实例化是什么呢,给大家举个例子吧,我们修房子之前是不是需要计划好这栋房子的样子呢?那么我们是不是需要让设计师画好图纸呢,同样的道理,我们的类也是这样

 类相当于图纸,而实例化对象就是我们按照图纸建造的房屋。我们看段代码理解一下

对象大小 

其实对象大小的计算也是和C语言是一样的,遵循内存对齐规则,我们来稍微复习一下。

  1.第⼀个成员在与结构体偏移量为0的地址处。

  2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

  3.注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

  4.VS中默认的对⻬数为8

  5.结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

  6.如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤小就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍

我们下面来看一段代码,想想为什么会这样。

A和B的内容都是空的,为什么打印出来的A和B 的大小都是1呢?

这是因为如果连大小都没有的话,那么我们怎么知道A和B存在过呢,所以这里起到的是占位符的作用。 

this指针

我们下面看一段代码

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?,我们的this指针就派上用场了。

编译器编译以后,会自动给类成员函数的第一个形参的位置加一个该类的this指针。

void Init(Date* const this, int year,int month, int day)

就是上面红色字体这样,我们就知道是使用的d1的Init函数了。

使用Init函数时,我们需要给d1的年月日赋值,那么就是this指针的作用,就像这样

this->_year = year;

但是我们写代码的时候并不是这样写的,只是他的底层是这样的,我们就像平常一样赋值就行了,到时候编译器会自动加上的。

注意事项:我们在形参位置不可以显示使用this指针,但是在函数内部可以显示使用this指针。

其实this指针也相当于一个形参,所以他应该是在寄存器中。


类的默认成员函数

构造函数
 

构造函数虽然叫构造函数,但是他的作用并不是开创空间的,而是初始化实例化对象,就可以代替我们之前写的Init函数,但是构造函数有自己的规则。构造函数的特点:

1. 函数名与类名相同。

2. ⽆返回值。 (返回值啥都不需要给,也不需要写void,不要纠结,C++规定如此)

3. 对象实例化时系统会⾃动调⽤对应的构造函数。

4. 构造函数可以重载。

5. 如果类中没有显式定义构造函数,则C++编译器会⾃动⽣成⼀个⽆参的默认构造函数,⼀旦⽤⼾显式定义编译器将不再⽣成。

这就是那三种构造函数。我们不写,编译器默认⽣成的构造,对内置类型成员变量的初始化没有要求,也就是说是是否初始化是不确定的,看编译器。对于⾃定义类型成员变量,要求调⽤这个成员变量的默认构造函数初始化。如果这个成员变量,没有默认构造函数,那么就会报错,我们要初始化这个成员变量,需要⽤初始化列表才能解决,初始化列表,我们下个章节再细细讲解。

 析构函数

析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对象中资源的清理释放⼯作。析构函数的功能类⽐我们之前Stack实现的Destroy功能,⽽像Date没有Destroy,其实就是没有资源需要释放,所以严格说Date是不需要析构函数的。

 

有一个小tips告诉大家是否要自己写析构函数,我们只要判断成员函数是否要申请资源,如果申请了,就和实现栈一样,那就要自己写析构函数,如果不需要,像日期类一样,那就不要自己写析构函数。

拷贝构造函数 

如果⼀个构造函数的第⼀个参数是⾃⾝类类型的引⽤,且任何额外的参数都有默认值,则此构造函数也叫做拷⻉构造函数,也就是说拷⻉构造是⼀个特殊的构造函数。


拷⻉构造的特点:

1. 拷⻉构造函数是构造函数的⼀个重载。

2. 拷⻉构造函数的第⼀个参数必须是类类型对象的引⽤,使⽤传值⽅式编译器直接报错,因为语法逻辑上会引发⽆穷递归调⽤。 拷⻉构造函数也可以多个参数,但是第⼀个参数必须是类类型对象的引⽤,后⾯的参数必须有缺省值。

3. C++规定⾃定义类型对象进⾏拷⻉⾏为必须调⽤拷⻉构造,所以这⾥⾃定义类型传值传参和传值返回都会调⽤拷⻉构造完成。

4. 若未显式定义拷⻉构造,编译器会⽣成⾃动⽣成拷⻉构造函数。⾃动⽣成的拷⻉构造对内置类型成员变量会完成值拷⻉/浅拷⻉(⼀个字节⼀个字节的拷⻉),对⾃定义类型成员变量会调⽤他的拷⻉构造。

我们根据规则,写出的拷贝构造是这样的,但是我们要思考一个问题,就是为什么拷贝构造的参数是引用呢?并且还加了一个const。

我们注意一下上面的第三条,标红的那一条,说明了传值传参都会调用 拷贝构造函数,那么我们如果不用引用的话就会变成传值传参,那就回一直调用拷贝构造,如果语言不好理解,那我们看一个图片你就明白了。

运算符重载 

1.当运算符被⽤于类类型的对象时,C++语⾔允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。

2.运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。和其他函数⼀样,它也具有其返回类型和参数列表以及函数体。

3.重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数,⼆元运算符有两个参数,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数。

4.如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数⽐运算对象少⼀个。

5.运算符重载以后,其优先级和结合性与对应的内置类型运算符保持⼀致。

6.不能通过连接语法中没有的符号来创建新的操作符:⽐如operator@。

7. .* :: sizeof ?: . 注意以上5个运算符不能重载。

8.重载操作符⾄少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int operator+(int x, int y)

9.⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义,⽐如Date类重载operator-就有意义,但是重载operator+就没有意义。

10.重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,⽆法很好的区分。C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,⽅便区分。

是不是觉得这个运算符重载的规矩还挺多的。其实还是很实用的,我们很多地方都要用到。

这就是他的完整用法了。 

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

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

相关文章

软件测试面试八股文(含答案解析+文档)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计,到…

如何在D盘创建虚拟环境?包括安装PyTorch和配置PyCharm

摘要:本文首先在D盘创建了虚拟环境,然后在虚拟环境中安装了PyTorch,最后配置了pycharm的解释器。 1. 在 D 盘创建虚拟环境 打开Anaconda Prompt 输入conda info --envs查看当前已有环境 创建自己的虚拟环境,打算命名为py310&…

一文彻底搞懂大模型 - GPT和LlaMA的模型架构

GPT vs LlaMA GPT与LlaMA,作为大语言模型的两大巨擘,均基于Transformer架构却各有千秋。GPT系列以强大的生成能力著称,通过不断增大的参数规模引领复杂语言与推理任务的前沿;而Llama则以开源姿态,通过技术创新提升模型…

江协科技stm32————10-5 硬件I2C读写MPU6050

步骤 一、配置I2C外设,对I2C2外设进行初始化(MyI2C_Init) 开启I2C外设和对应的GPIO口的时钟把I2C对应的GPIO口初始化为复用开漏模式使用结构体配置I2CI2C_Cmd,使能I2C I2C_GenerateSTART //生产起始条件 I2C_GenerateSTOP /…

MySQL:复合查询

MySQL:复合查询 聚合统计分组聚合统计group byhaving 多表查询自连接子查询单行子查询多行子查询多列子查询from子查询 合并查询unionunion all 内连接外连接左外连接右外连接全外连接 视图 MySQL 复合查询是数据分析和统计的强大工具,本博客将介绍如何使…

黑马点评——商户查询缓存(P37店铺类型查询业务添加缓存练习题答案)redis缓存、更新、穿透、雪崩、击穿、工具封装

文章目录 什么是缓存?添加Redis缓存店铺类型查询业务添加缓存练习题 缓存更新策略给查询商铺的缓存添加超时剔除和主动更新的策略 缓存穿透缓存空对象布隆过滤 缓存雪崩解决方案 缓存击穿解决方案基于互斥锁方式解决缓存击穿问题基于逻辑过期的方式解决缓存击穿问题…

【教程】实测np.fromiter 和 np.array 的性能

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 目录 函数简介 np.fromiter np.array 测试代码 实验结果 结果分析 实验总结 学长想说 函数简介 np.fromiter np.fromiter 是 NumPy 提供的一…

【SuperCraft AI:无限工作流画布】

SuperCraft AI:无限工作流画布 SuperCraft 是一款全新的 AI 工具。它具有将手绘草图转换为不同产品图像的功能,提供了一个无限大的协作画布,让设计师能够在此手绘草图,并利用生成式 AI 技术将草图转化为高质量的 2D 图像和 3D 渲…

NC 二分查找-II

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 请实现有重复…

Unity TreeView扩展

实现效果 这里原来是做的一个检测网络、事件回调耗时的工具。简单改了成了一个演示TreeView的demo。实现了TreeView的基本功能并且实现了对列的排序。TreeView还可以制作点击,双击,右键等事件,但这里暂时不需要用到。 思维导图 工程&#xf…

arcgisjs4.0 内网部署字体不显示问题处理

问题背景问题定位解决方案 问题背景 内网环境,通过压缩包的hash值验证了包是一摸一样的,ningx也读到了index.html,但是网格的字提显示出不来,并且地图上的注记文字均不显示 本地环境地图情况: 内网环境地图情况&…

Bluetooth: att protocol

一篇搞懂 ATT 支持的东西都有什么。 READ_BY_GROUP_TYPE_REQ/RSP 如下是 Spec 内容: The attributes returned shall be the attributes with the lowest handles within the handle range. These are known as the requested attributes.If the attributes with the requeste…

石油设备和相关机械都包涵那些?

关键字:钻杆测径仪,泵管测径仪,固井管道直线度测量仪,输送管测径仪,输送管检测设备, 石油设备是指在石油和天然气的勘探、开发、生产、储存和运输等过程中使用的各种机械和装置。这些设备通常包括但不限于…

黄力医生科普:如何有效预防冠心病,这几个保健措施不可少!

冠心病,作为心血管系统的一种常见病,主要因冠状动脉粥样硬化导致管腔狭窄或闭塞,进而引发心肌缺血缺氧。此病多发于中老年群体,且具有一定遗传性。然而,无论发病因素如何,我们都可以通过一系列有效的预防措…

C++类和对象(6)——初始化列表

一般的初始化 class A { public:A(int a){ //一般的初始化&#xff0c;在{}括号里面给成员变量赋值_a a;cout << _a << endl;}~A() {}private:int _a; }; 用 初始化列表 初始化 当成员变量是以下两种情况时&#xff0c; 必须使用初始化列表&#xff01; cons…

单自由度无阻尼系统振动分析

特别感谢&#xff1a;https://www.bilibili.com/video/BV114411y7ab/?p6&spm_id_frompageDriver&vd_sourceebe07816bf845358030fc92d23830b29 本文图片该系列视频 tips&#xff1a;关于特征方程与振动方程&#xff1a; 特征方程有助于我们理解和确定系统的固有频率和模…

【算法】贪心算法解析:基本概念、策略证明与代码例题演示

文章目录 1. 什么是贪心算法&#xff1f;2. 贪心算法的特点3. 例题&#xff08;贪心策略&#xff09;① 找零问题② 最小路径和③ 背包问题 4. 贪心策略证明 1. 什么是贪心算法&#xff1f; 在学习贪心算法之前&#xff0c;一定要理解的是贪心策略&#xff1a; 贪心策略是一种…

Ubuntu中qt类与类信号槽的创建及使用

今天学习到了新的一个小玩意&#xff0c;我们在QT中创建一个大项目的时候一般会创建多个类&#xff0c;那我们就来学习一下如何在自定义的类中声名和使用信号与槽函数。 首先我们CTRLn来创建我们新的类&#xff1a; 我们创建新的C的类&#xff0c;一个School&#xff0c;一个S…

举办知识竞赛是线上好还是线下好

举办知识竞赛线上和线下各有优势&#xff0c;选择哪种方式取决于具体的需求和条件。 线上举办知识竞赛的优缺点&#xff1a; 优点&#xff1a; 便捷性&#xff1a;线上竞赛不受地域限制&#xff0c;参与者可以在任何有网络的地方参与。 选手数&#xff1a;可以同时满足人数较…

单门店共享自习室小程序系统源码搭建对接门禁和空开api

共享自习室小程序&#xff0c;单门店共享自习室小程序&#xff0c;有源码&#xff0c;对接门禁和电控api接口&#xff0c;php开发语言&#xff0c;前端是uniapp。可以源码搭建&#xff0c;也可以二开或定制。 一 用户端 在线选择预约时间&#xff0c;选择座位&#xff0c;选择…