作者:几冬雪来
时间:2023年4月21日
内容:C++类和对象
目录
前言:
在上一篇博客中我们对C++中的引用的知识做了拓展的讲解,同时也引入了新的内容——常引用和auto,并且也对它们进行了一个大致的说明讲解。今天我们将开展C++知识的一个新的知识的讲解,并且这节课也可以是我们C++中非常重要的一节课。
1.inline函数:
在我们日常写代码的时候,调用函数是我们必不可少的一个操作,那么在调用函数的过程中就难免会产生消耗,而栈帧就是我们调用函数中最大的消耗。
类似我们下面的这个代码:
在这里我们的Add要被调用10000次,所以在这里我们就需要建立10000个栈帧,这在我们看来就是非常浪费的一种行为。
在C语言中我们使用宏的方式去解决这个问题。但是宏在这里有一些缺点所在,在介绍C++的时候我们有说过在这个板块我们需要的是用C++的知识去填补C语言的坑,那么这种情况我们该怎么用C++去书写呢?
在C++中如果我们要解决这个问题的话就要了解到一个新的词语——inline函数。
但是在这里,inline函数并不是可以作用于全部函数之上的,它的应用有条件的限制。
首先,我们的inline函数适用的是短小的频繁调用的函数。如果太长可能会导致这里我们的代码膨胀。
那么有人就要问了,在这里我们是不是要先去判断其长短后,再考虑要不要去使用inline呢?其实这里不用想那么多。因为在这里,我们的编译器会帮助我们把关。inline对于编译器仅仅只是一个建议,最终决定是否使用成为inline,由编译器决定。
那么在上面情况下我们的inline会被否决掉呢?我们将例子举出来:
1.比较长的函数。
2.递归函数。
3.默认debug的模式下,inline不会起作用,否则不方便调试。
同时这里要知道,我们的inline函数的声明和定义不能分离。inline不会进符号表,分离可能导致链接出问题。
2.auto(补充):
在上一篇博客中我们讲解了auto的内容,今天我们将对其进行一个知识的补充。
首先我们的auto在同一行内不能这样使用,类似前面一个整形类型,后面一个浮点型。
其次,我们的auto也不能用来定义数组的类型。
最后,在这里我们的auto不能用来作为函数的参数。
还有就是这里auto在空指针这里会出现一个坑。
在这里左边这里,第二个函数引用即使为空,它并不会去调用第二个函数,而是去调用第一个函数。只有像我们第一个代码引用了——nullptr,它才可以成功去调用第二个函数。
3.类:
从这里开始,我们就开始进入类和对象的学习了,那么在这里什么是类呢,这里我们写一个代码出来。
在这里我们的C++兼容C语言,struct以前的用法依旧可以使用,同时在这里我们的struct升级成为了类。
同样的我们的struct升级成为了类,那么在这里我们的结构体的成员也会发生改变,原本在结构体中我们只能定义成员变量,而在这里我们可以定义成员函数。
这里就是我们的写法,同时在这里我们的调用也是十分的简单。在结构体定义,C++中我们更经常
用class来代替struct。 但是在这里如果使用class的话就牵扯出来了一个权限的问题。
4.类的访问限定符及封装:
在C++我们定义了3种访问限定符。
同样的这里也有我们访问限定符的一系列的说明。
那么在这里我们的公有和私有是什么意思?用现实世界的例子举例,比如我们的个人信息中的身份证号码,家庭住址等不想让别人知道的,这里就对应着私有。像性别,年龄,性命等可以让别人知道的在这里就指的是公有。代码中也是如此,不想让别人使用的这里我们就定义为私有,可以别人返回和使用的我们就定义为公有。
这里就是我们公有和私有内容的范围,类似我们的这个图从public开始到我们写一个访问限定符之间的内容就都是公有的,直到遇到我们的访问限定符private后接下来的内容变为私有,因为后面没有访问限定符,所以到函数结束的位置其余的内容都为私有。
同时的,在这里我们的class和struct都可以作为类,访问限定符也都适用于类,所以它们之间可以进行替换。唯一不同的是在这里我们的class默认内容为私有,struct默认内容为公有。
在这里我们也要注意一个点,那就是在我们的类中,声明和定义是可以进行分离的。只不过这里在定义的时候,我们需要在Init函数的前面加入一个::操作符来指向。
第二个要了解的点是:在类里面直接定义的函数默认就是inline。
5.封装:
在我们的面向对象中有三大特性:封装,继承,多态。而在这里我们将对面向对象中的封装进行讲解。
那么什么是封装呢?封装说的是:将数据和操作数据的方式进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
对于我们的代码来说,封装是一种更好的管理,它可以杜绝一些我们坏的行为。
这里就是我们封装的作用和实现。
6.类域:
在这里我们接下来就要介绍一下类域了。
我们当初介绍域的时候有说过,平常我们写代码的时候,一般都是先访问局部域,再访问全局域。如果我们的命名空间域没有特别指向或者展开的话,域中的量我们不会访问。
但是类似我们的函数定义和声明那里的话,我们是先访问局部域,再访问类域,最后访问全局域。
7.类的实例化:
这里类的实例化指的是用类类型创建对象的过程,我们称为类的实例化。
在我们的类中不能存储数据。只有类进行了实例化之后我们才可以向其中存储数据。
在这里我们的第一种方式是访问的top,而top在声明中,所以这里我们并不能给声明的内容数据。而在第二段代码中的话,就是开辟了一块空间,在这里我们就可以给数据。
进行了我们来计算它们的大小。
在以前我们的结构体中只有结构体成员,而现在在结构体中还多出了成员函数,那么在这里我们的st1的大小是多少呢?
在这里我们算出st1的大小是12,那么这是为什么呢?因为在这里我们只算成员的变量不算成员的变量,不算成员的函数,对象中只存储了成员变量,没有存成员函数。
在这里我们的st1和st2调用的不是同一个函数。但是这里我们访问Init的代码,它们调用的是同一块地址,也是同一个函数。这就是我们说的对象中只存储了成员变量,没有存成员函数的原因,在这里我们也可以为st1和st2中都定义上Init,但是这样做太过于浪费,因此我们一般将其放在公共区域,要调用的话也直接去公共区域调用就行了。
结尾:
在这里,我们就开始进入我们C++的重点内容开始学习了,接下来我们所学习的内容将会一次比一次要难,要掌握C++我们还是任重道远。最后希望这篇博客可以为各位带来一些帮助。