类和对象—5

Posted 麋璐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类和对象—5相关的知识,希望对你有一定的参考价值。

首先要看的是最后两个默认成员函数:取地址及const其地址操作符重载问

对于普通对象的成员取地址重载就很简单了:

                           类和对象—5_初始化列表

直接实现即可,而对于由const的取地址操作符重载我们就需要改变普通对象的成员取地址重载了:

类和对象—5_成员变量_02

       接下来我们再来聊聊const成员,const修饰类的成员函数:将const修饰的类的成员函数称之为const成员函数,const修饰类成员函数,实际上修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。举个例子:

类和对象—5_成员变量_03

       我们在参数后加入const时,就代表const修饰了这个成员函数中所有的参数,并且该函数的所有参数都无法改变(改变就会报错),相当于对程序可以起到保护作用。再举个例子:

类和对象—5_初始化列表_04

这样应该很好理解了吧。

       注意:对于普通对象,即可调用普通成员函数,又可以调用const成员函数;对于const对象,只能调用const成员函数,不能调用普通成员函数。并且const成员函数无法调用普通成员函数(可能会间接修改),普通成员函数可以调用const成员函数。若要用const定义成员变量,必须初始化。const修饰的是一个常量,且在编译阶段进行替换。

这时问题来了,如果我们只想让成员函数中某个参数改变,其他参数不改变,那我们该怎么办呢??

       这时我们就要引入关键字:mutable,在开始定义类的成员变量时,可以给要改变的成员变量最前面加入mutable,这样类中的const成员函数中,我们用mutable定义的成员变量就可以被修改。

          类和对象—5_初始化列表_05

       接下来我们再来谈谈之前说过的构造函数,我们都知道,在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值;但是,严格意义上来说,这不能称为对类对象成员的初始化,只可以称为时函数体中赋初值(初始化只能有一次,赋值可以有很多次)。所以,接下来我们引入了初始化列表这个概念。

初始化列表:以一个冒号开始,接着时一个以逗号分开的数据成员列表,每个“成员变量“后面跟放在括号中的初始值或表达式,例如:

       类和对象—5_初始化列表_06

注意:

1.每个成员变量在初始化列表中只能出现一次

2.类中包含以下成员,必须放在初始化列表位置进行初始化:引用成员变量,const成员变量,自定义类型成员变量

3.尽量使用初始化列表初始化,因为不管你是否调用初始化列表,对于自定义成员变量,都会先用初始化列表

4.成员变量在类中的声明次序就是其在初始化列表中的初始化顺序(与其在初始化列表中的顺序无关)

       接下来我们再来讲一个关键词:explicit。构造函数不仅可以构造与初始化对象,对于单参的构造函数,还有类型转换的作用,我们来看个例子:

        类和对象—5_初始化列表_07

      我们开始其实会感到很奇怪,为什么整形可以赋值给日期类对象呢??其实d1=2021这步的代码逻辑是,当编译器走到d1=2021时,先使用2021调用单参构造函数创建一个临时对象,再使用临时对象给dd进行赋值,最后再调用~Date将临时对象销毁。(不建议使用单参构造函数),当我们使用explicit修饰构造函数时,就会禁止单参构造函数进行隐式转换。

那么如果现在有个需求:我们需要知道一个类创造了多少对象?那么我们该怎么写呢?

我们先来看代码:

类和对象—5_成员函数_08

       我们调试就会出现问题,本来应该是都存储自己创建的一个对象,但是d3创建了两个对象,所以普通成员变量不行。因为普通成员变量的每个对象都存在一份,并且和具体对象挂钩,而我们需要统计的对象不应该和对象绑定在一起,应该是所有对象共享的。

接下来我们在使用全局变量看看:

类和对象—5_成员函数_09

       我们就看出,这样的结果符合我们想要的,就是一个变量去统计全部的类创价的对象。但是,虽然代码很简单并且可以达到我们预期的效果,但是代码还是不安全,全局变量在整个工程中都是可以被成员任意访问的,而且如果我们不小心写错了,也有可能导致结果出错。

所以我们就需要一个共享的变量,也就引入了static成员

       static成员,声明为static的类成员称为类的静态成员,用static修饰的成员变量,称为静态成员变量;用static修饰的成员函数,称为静态成员函数。静态成员变量在类中只是声明,需要在类外重新进行定义(类外不加static,但要加类名::);静态成员变量没有储存在对象中,不是具体某个对象的属性,它所有对象共有的成员变量;静态成员变量可以通过对象,静态成员变量名||类名::静态成员变量名字;静态函数受访问限定符限制;静态函数变量不能在构造函数初始化位置进行初始化

我们还是拿上面的代码举例子:

                     类和对象—5_成员变量_10

                 类和对象—5_成员变量_11

       如果我们想在类外调用静态成员变量可以在类内写一个函数,返回静态成员变量的值,再在外部调用(毕竟静态成员变量共享,也不用特指某个对象)

类和对象—5_初始化列表_12

注意:在静态函数中是没有this指针的,也就是我们不能调用非静态成员变量;但是,普通成员函数可以调用静态成员变量和函数。静态成员函数不能设置const成员函数(之前讲过,const修饰的就是this指针)。静态成员函数不能作为虚函数(后面会讲)

好了,今天的内容就到这里,希望大家下去后可以多多理解,多多观看,感谢大家可以看到最后!!!


以上是关于类和对象—5的主要内容,如果未能解决你的问题,请参考以下文章

第四章总结

在用Gson解析对象的时候,json数据中没有的字段,会赋初值。

在c语言中给变量赋初值有啥作用

Random类

类和对象

my java note -------类的初始化和加载