作者:几冬雪来
时间:2023年5月10日
内容:C++类和对象内容讲解
目录
前言:
今天我们依旧来继续讲解我们的类和对象,很快的我们的类和对象这一个板块的知识也都要学习完毕了。类和对象作为我们C++中一个重要的学习板块,我们需要多去了解它。
1.取地址操作符重载:
延续我们上一篇博客的内容,在上一篇博客中我们讲解了许多操作符的重载的方式。
在这里就剩下我们最后一个要知道的操作符重载,也就是取地址操作符重载。
但是这个操作符在实际应用中基本不去进行应用,所以在这里我们将其代码大致的写出来看看即可。
这里就是我们的取地址操作符的代码的书写方式。
2.构造函数(进阶):
在前不久我们学习了构造函数,并且也可以书写构造函数,而今天我们就要来对构造函数进行延伸的讲解。
1.初始化列表:
在以前我们写构造函数的时候,一般都是对构造的函数体进行赋值。
类似于上面的这种方式。
但是今天我们要讲解另一种方式——初始化列表。
在这里我们的初始化列表是:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号内的的初始值或表达式。
就是我们这里的这种书写方法。
同时在这里我们的初始化列表也有它的规定所在。
那么我们的初始化列表有哪些规定呢?
首先是我们的第一点,每个成员变量在初始化列表中最多出现一次,也就是只能初始化一次。
这一个点非常的容易理解,毕竟在初始化的时候我们不能将一个变量既初始化为10又初始化为20,这是不合理的。
接下来就是我们的第二点。
首先我们的引用成员变量和const成员变量必须在初始化列表位置进行初始化。
然后就是我们的自定义类型。
在这里我们的自定义会去调用到它的默认构造。
因为aobj是我们的自定义类型,在编译器中它会自动处理会去调用它的默认构造,在初始化列表中调用,但是它可以不出现。
因此即使我们在_ref和_n定义处没有写我们的自定义类型,它还是会进行调用的操作。
但是并不是内置类型就完全不进行处理。
类似我们这里的x = 1的操作,它并不是赋值操作而且缺省值。
而这里的缺省值是给初始化列表的,如果在定义处我们进行初始化的话,缺省值就没有作用了。
同样的我们的自定义类型也是如此。
但是如果我们的A没有默认构造,那么在定义处我们不写aobj是不会通过的,在这里我们要显示着给值。
但是在这里我们的引用就会出现问题,记得我们在引用处曾经又说过,指针有野指针,引用没有野引用这一个概念。
虽然可以跑起来,但是从语法上来看这个代码是不对的,这里就类似我们野指针一样的野引用。
因此我们也可以得知引用并不是万能的。
这里有人就要问了,既然我们的初始化列表这么有用的话是不是就不需要用函数体赋值了?
其实不然,虽然初始化列表可以解决我们的大多数的问题,但是它并不是万能的,如果在这里我们类似开辟空间,要去检查空间是否成功开辟的话,初始化列表就没办法办到,这里就需要我们的函数体赋值。
并且这里也还有一个坑的存在。
像我们上面的这个代码,假如我们给a1一个值的话,这里打印出来的a2是一个随机值。
因为成员变量在类中的声明顺序就是其初始化列表的初始化顺序,与其在初始化列表的先后顺序无关。
这里给一个建议,那就是声明的顺序和定义的顺序保持一致。
同时这里我们还要知道这一个点。
2.static成员:
接下来我们就来讲解static成员。
这里我们先写一串代码来统计A创建了多少个对象。
在这里我们就计算创建的个数。
在这里我们通过打印可以简单的看出来结果。
在这里我们的第一次只能调用aa0,在第二次打印的时候,因为实参传给了形参,自定义类型传参要调用拷贝构造,所以是4次。
在出作用域后,销毁所以最后是3次。
在这里我们对代码稍加修改一下,修改成上面这个样子。
那么这个时候我们可以看见两次调用83行的结果都是3。
这是因为aa2在静态区,不在栈帧中,它只会被定义一次。
但是我们这种写法就有劣势所在,因为我们的_scount是全局变量,因此它在任何地方都可以被改变,就像我们在Func对,_scount进行++操作是可以的。
所以在这里为了解决这个方法,我们对其进行了封装的操作。
这里我们的静态成员变量也是这个样子进行声明的。
但是在这里我们的定义就有所不同,因为它不属于某个对象自己的成员,它属于全局是每个对象共享的。
这样子定义是不行的。
因此我们要将它在类的外面进行定义。
这里有人可能就要问了,在这里我们的_scount不是属于私有的吗,为什么能在类的我们进行定义操作?
这里我们只能理解为它有一次突破私有进行定义的操作。
但是实际上它还是私有的,我们不能直接对其进行访问。
这里如果要对其进行访问的话,这里就要写一个我们的静态成员函数。
因此在这里我们可以知道,通常静态成员函数和静态成员变量是配套出现和使用的。
但是在这里有一个需要我们注意的点,那就是静态成员函数不能访问非静态的成员。
因为它没有this指针。
那有人就问能不能我们能不能在声明的时候给其一个缺省值来使用。
这也是不行的,因为我们的缺省值是给初始化列表的,但是我们的静态的没有初始化列表。
因此它会进行报错。
因此静态成员变量不能给缺省值。
结尾:
在这里,我们的这一期的类和对象也学习完毕了, 最近C++类和对象的难度可谓是提升了不止一点,如果只是简简单单的看的话效果是很低的,因此要学好这方面的知识还要多去刷题来提升自己。最后希望这篇博客能为各位的学习带来帮助。