详说 类和对象

类怎么定义

类是什么呢?类就是我们上篇文说的命名空间,单独创建一个域,自己有自己的生命空间,那么类怎么定义呢?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.rhkb.cn/news/413205.html

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

相关文章

汽车乘客热舒适度大挑战,如何利用仿真技术提高汽车环境舒适度

舒适性在人们选择汽车的决定性方面占比越来越重,而汽车乘员舱环境的舒适性是指为乘员提供舒适愉快便利的乘坐环境与条件,包括良好的平顺性、车内的低噪声、适宜的空气环境以及良好的驾驶操作性能。 舒适性 经济性 安全性、动力性 典型的乘员舱热舒适性模…

laravel的队列的使用

laravel队列 laravel的特性:laravel队列可以基于不同的后台存储服务提供统一的api,后台存储服务包括 Redis MySQL等。队列实现了业务解耦,异步处理,错误重试的功能。比如调用第三方api,无法保证api的可靠性&#xff0…

Transformer 与传统模型Informer

Transformer 与传统模型:Informer 如何改变时间序列预测的规则 Transformers 是那些聪明的注意力构建者,它们在机器学习的各个领域掀起了波澜。但在时间序列预测领域,它们才真正大显身手。你可能会问,为什么?想象一下,有一个水晶球,它不仅能看到未来,还能理解导致未来的…

TCP协议 配合 Wireshark 分析数据

在TCP连接中,无论是客户端还是服务端,都有可能成为发送端或接收端,这是因为TCP是一个全双工协议,允许数据在同一连接中双向流动 客户端(Client):通常是指主动发起连接请求的一方。例如&#xf…

宠物空气净化器有用吗?为什么养宠家庭要买宠物空气净化器?

身为一个鼻炎患者,却喜欢猫咪,所以毅然决然的养了两只宠物,而且还是长毛猫,不要问为什么鼻炎还买两只猫咪,因为怕一只猫咪孤单,所以养了两只。对于很多人来说,猫咪就像焦虑不安时的精神搭子&…

如何让私域服务赢得用户的心?

私域流量的概念在当今的商业环境中已经变得极为重要,许多品牌和企业都投入大量资源尝试通过各种策略吸引并保留用户。然而,单纯的流量积累并不足以确保商业成功。当面对用户的沉默、缺乏活跃度以及无法变现的困境时,我们必须重新审视私域流量…

语音控制开关的语音识别ic芯片方案

语音控制开关是一种基于语音识别技术的设备,它通过内置的语音识别芯片,将用户的语音指令转化为电信号,从而实现对设备的控制。例如在智能家居设备上的应用,通常需要连接到家庭的Wi-Fi网络上,以便与智能手机或智能音箱等…

Java之初始泛型

1 包装类 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 基本数据类型包装类byteByteshortShortintIntegerlongLongfloatFloatdoub…

FaceFormer嘴形同步论文复现

一、项目地址 https://github.com/EvelynFan/FaceFormer 二、复现过程 1、项目环境 系统:Ubuntu 18.04.1 python版本:Python 3.7 使用conda创建一个虚拟环境,安装requirements.txt中所需要的库 2、安装ffmpeg 教程网址:http…

8个Python编程进阶常用技巧!

介绍 Python 炫酷功能(例如,变量解包,偏函数,枚举可迭代对象等)的文章层出不穷。但是还有很多 Python 的编程小技巧鲜被提及。因此,本文会试着介绍一些其它文章没有提到的小技巧,这些小技巧也是…

Selenium+Python自动化测试环境搭建

1. 什么是Selenium? Selenium主要用于web应用程序的自动化测试,但并不局限于此,它还支持所有基于web的管理任务自动化。 2、selenium 自动化流程如下: 自动化程序调用Selenium 客户端库函数(比如点击按钮元素&#xff…

【计算机组成原理】六、总线:3.操作和定时

5.操作和定时 文章目录 5.操作和定时5.1总线传输的四个阶段5.2总线定时5.2.1同步通信5.2.2异步通信5.2.3半同步通信5.2.4分离式通信 2.3按时序控制方式 同步总线异步总线 5.1总线传输的四个阶段 总线周期: 申请分配阶段:由需要使用总线的主模块&#…

计算机组成原理:实验一运算器组成实验

一、实验目的 1.掌握算术逻辑运算加、减、乘、与的工作原理。 2.熟悉简单运算器的数据传送通路。 3.验证实验台运算器的8位加、减、与、直通功能。 4.验证实验台的4位乘4位功能。 5.按给定数据,完成几种指定的算术和逻辑运算。 二、实验电路 图1.1 运算器数据…

约瑟夫环和一元多项式

约瑟夫环 一、问题描述 假设有 n 个人围成一圈,从第一个人开始报数,报数到 m 的人将被淘汰出圈,然后从下一个人开始继续从 1 报数,如此重复,直到最后只剩下一个人。求最后剩下的这个人的编号。 二、问题分析 可…

DDR3详解

1.DDR3简介 DDR3 SDRAM,全称第三代双倍速率同步动态随机存取存储器,简称 DDR3,双倍速率(double-data-rate),是指时钟的上升沿和下降沿都发生数据传输;同步,是指DDR3数据的读取写入是…

使用 nuxi build-module 命令构建 Nuxt 模块

title: 使用 nuxi build-module 命令构建 Nuxt 模块 date: 2024/8/31 updated: 2024/8/31 author: cmdragon excerpt: nuxi build-module 命令是构建 Nuxt 模块的核心工具,它将你的模块打包成适合生产环境的格式。通过使用 --stub 选项,你可以在开发过程中加快模块构建速度…

linux Vim的安装和基本使用

Vim 什么是 Vim Vim是一个高度可定制的文本编辑器,源自Unix系统的vi编辑器。它被广泛用于类Unix系统中,包括Linux、Mac OS和Windows平台。Vim特别受到程序员的青睐,因为它提供了丰富的编程功能,如代码补全、编译及错误跳转等。这…

Kubernetes 上安装 Jenkins

安装 Helm curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash添加 Jenkins Helm 仓库 首先添加 Jenkins Helm 仓库 helm repo add jenkins https://charts.jenkins.io helm repo update安装 Jenkins 使用 Helm 安装 Jenkins 的最新版本&…

产品经理角度分析:朋友圈点赞与评论仅共同好友可见

你有没有在刷朋友圈时,看到某位朋友发了条状态,下面一堆点赞和评论,然后他自己来个“统一回复下,感谢大家”? 这种现象就像是在朋友圈里开了个小型新闻发布会,大家在台下疯狂举手,结果发言人最后…

ip地址变化是什么意思?手机地址ip一直变化怎么办

IP地址作为互联网设备的唯一标识,‌其稳定性对于网络连接至关重要。‌然而,‌手机IP地址频繁变动可能带来一系列问题。‌本文将深入探讨IP地址变化的含义、‌IP地址频繁变动的原因,‌以及提供手机地址IP一直变化的有效应对策略。‌ 一、IP地址…