【C++】类和对象 从入门到超神

目录

一、 初始化列表

1.1 自定义类型成员(无默认构造函数)

1.2 const 成员变量

1.3 引用成员变量

1.4 初始化列表的注意事项

1.5 explicit 关键字

二、 static成员

三、 友元

3.1 友元函数

3.2 友元类

四、 内部类


一、 初始化列表

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

现在举例一个必须使用初始化列表的场景:

1.1 自定义类型成员(无默认构造函数)

如果一个类中有一个自定义类型的成员,我们在构造函数中也想初始化该成员,在不使用友元和不改变访问限定符的情况下,那构造函数应该要这样写:

 那我们只能先创建一个对象,然后进行赋值,这样的方式低效,而且会有以下这种问题。

当 Time 类不提供构造函数时(即构造函数无缺省值),这种方式就行不通了。

 所以我们只能使用初始化列表进行初始化,这就是一个必须使用初始化列表的地方。

同样,如果自定义类型存在构造函数,也可以使用初始化列表,这里就不演示了。

1.2 const 成员变量

我们知道,只能在定义的时候初始化,后面则不能进行修改了,这种情况下也必须使用初始化列表,要不然无法初始化。

1.3 引用成员变量

除了 const ,我们知道还有引用变量在定义的时候就要初始化要,所以,这种情况也要使用初始化列表,我们来看看是怎么初始化的吧。

 上面就出现了一个问题,_y 的改变并没有影响到 x 。

 解决方法:传引用即可。

1.4 初始化列表的注意事项

通过以上的了解,总结如下:

结论:

  1. 自定义类型成员,推荐使用初始化列表初始化。
  2. 初始化列表可以认为是成员变量定义的地方。
  3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表初始化,对于自定义类型成员变量,一定会先使用初始化列表初始化。
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

第二点结论我们可以推出C++11中打的那个补丁,在成员声明的地方给缺省值的作用。

这个缺省值其实就是给的初始化列表。大家可以看下面这个变化过程,如果函数体内没有 _year=year 这条语句,其实声明时的缺省值默认给了初始化列表。

 第三点结论中,虽说推荐使用初始化列表,但是有一些场景使用函数体内初始化也是很不错的,比如在 malloc 开辟空间时:

关于第四点结论,我们来看一道题目就懂了。 初始化按声明顺序初始化

1.5 explicit 关键字

我们先来看以下两种创建方式,

其中第一个 是直接将2022传参条用构造函数,

另外一个是根据int 类型的2022构造一个 Date 类型的临时变量,然后将该临时变量拷贝给 d2 ,只不过这个过程被编译器所优化,变成了直接调用构造函数。

这本质是一个隐式类型的转化,就像就 int 型数据赋值给 double 型数据类似。

而 explicit 关键字的作用就是阻止这种隐式类型的转化。那我们来看看加上explicit 关键字后的效果。


二、 static成员

 2.1 概念

声明为 static 的类成员称为类的静态成员,用 static 修饰的成员变量,称之为静态成员变量;

用 static 修饰的成员函数,称之为静态成员函数。

静态成员变量一定要在类外面进行初始化。

静态成员变量声明和初始化举例:

 静态成员函数:

 2.2 特性

  1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
  2. 静态成员变量必须在类外定义,定义时不添加 static 关键字,类中只是声明。
  3. 类静态成员即可用 类名:: 静态成员对象.静态成员来访问。
  4. 静态成员函数没有 this 指针,不能访问任何非静态成员。
  5. 静态成员也是类的成员,受 public、protected、private 访问限定符的限制。

特性一:所有类对象共享

特性三:有两种访问方式,(注意:静态成员同样受访问限定符限制) 

特性四:

 特性五:


三、 友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

友元分为:友元函数友元类

3.1 友元函数

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数不属于任何类,但需要在想要进行友元的类中进行内部声明,声明时需要加 friend 关键字

使用场景:

我们想写一个打印 Date 类中成员的 流操作符重载的全局函数,如下:

此时,这个全局函数是无法访问到类中的私有成员的,所以我们加上 friend,声明这个全局函数是 Date 类的友元。

这样就可以直接访问类中的成员了,注意一定要是全局函数噢。

友元函数说明:

  1. 友元函数可访问类的私有和保护成员,但不是类的成员函数
  2. 友元函数不能用 const 修饰
  3. 友元函数可以在类定义的任何地方声明不受访问限定符的限制。
  4. 友元函数的调用和普通函数调用原理相同。 
  5. 一个函数可以是多个类的友元函数。

如果是想让一个类中的函数可以友元的访问另一个类中的成员,就要使用下面的友元类了,我们往下看。


3.2 友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非共有成员。

  • 友元关系是单向的,不具有交换性。

比如上述的 Time 类和 Date 类,在 Time 类中声明 Date 类为其友元类,那么可以在 Date 类中直接访问 Time 类的私有成员变量,但想在 Time 类中访问 Date 类中私有的成员变量则不行。

  • 友元关系不能传递

如果 C 是 B 的友元,B 是 A 的友元,则不能说明 C 是 A 的友元。

使用场景:

我们上面写的 Date 类和 Time 类,我们想在 Date 类中打印出 Time 类的成员,我们就可以使用友元类。

直接在 Date 中调用 Time类中的成员,很明显是不允许的,这时我们就可以使用友元类。 

使用友元后:


四、 内部类

概念:如果一个类定义在另一个类的内部这个内部类就叫做内部类。内部类是一个独立的类,他不属于外部类,共呢个不能通过外部类的对象取访问内部类的成员。外部类对内部类没有任何优越的访问权限。

 

注意:

  1. 内部类就是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
  2. 内部类在外部类的 public、protected、pribate 定义都是可以的,但是受访问限定符限制。
  3. 注意内部类可以直接访问外部类中的 static 成员,不需要外部类的对象/类名。
  4. sizeof(外部类)=外部类,和内部类没有任何关系。

特性1 与 特性 3:

因为 B 天生就是 A 的友元,所以 B 可以访问到 A 中的成员,我们以此举一个打印的例子: 

 特性4:

sizeof (外部类) 就是外部类的大小,与内部类无关,两个类的大小是没有关联的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brant_zero2022

素材免费分享不求打赏,只求关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值