【C++初阶】第4课—类和对象(下)

1. 初始化列表

  • 之前实现构造函数时,初始化成员变量主要通过函数体赋值。或者通过默认构造函数给全缺省值,构造函数初始化还有一种方式,那就是初始化列表

在这里插入图片描述


  • C++规定,初始化列表是在函数定义和函数体中间,从冒号:开始,每个成员变量后面要初始化的值要放在()里面,以逗号,作为初始化列表数据分割的依据
  • 每个成员变量在初始化列表中只能出现一次,初始化列表可以看做每个成员白变量定义初始化的地方
  • 引用成员变量、const修饰的成员变量、没有默认构造的类的类型变量,必须放在初始化列表初始化
  • 类外面的变量也可以放在初始化列表初始化

在这里插入图片描述


  • 当然也可以这样初始化

在这里插入图片描述


  • C++11支持成员变量在声明时给缺省值,这个缺省值不是赋值,而是给初始化列表的
  • 如果给定缺省值的成员变量在初始化列表已经有初始化值了,以初始化列表为准
  • 如果给定缺省值的成员变量没有在初始化列表显示,那么默认使用该缺省值
  • 初始化列表后面的函数体一般是给空的,除非特殊,可以根据需求在函数体初始化

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


  • 尽量使用初始化列表初始化,因为不在初始化列表初始化的成员也会走初始化
  • 对于没有显式在初始化列表初始化的自定义类型成员,如果也没有给缺省值,编译器会去调用这个成员类型的默认构造函数,如果默认构造函数也没有,编译器就会报错
  • 初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的顺序无关,如果你不想挨打的话,还是建议声明顺序和初始化列表顺序尽量保持一致
  • 练习题

在这里插入图片描述

  • 建议:初始化要不全写在初始化列表,要不就全给缺省

2. 友元

  • C++提供了一个可以突破访问类中限定符封装的成员,那就是友元。友元分为友元函数和友元类,在函数声明或函数定义前面+friend,并把友元函数放在类里面,位置随意
  • 外部友元函数可以访问类的私有和保护成员,友元函数仅仅是一个声明,他不是类的成员函数
  • 一般建议将友元函数放在public上面

在这里插入图片描述


  • 一个函数可以是多个类的友元函数

在这里插入图片描述


  • 友元类的成员函数可以是另一个类的友元函数,都可以访问另一个类的私有和保护成员
  • 友元类的关系都是单向的,不具有交换性,例如A类是B类的友元,但是B类不是A类的友元
  • 友元类关系不能传递,如果A类是B类的友元,B类是C类的友元,但A类不是C类的友元

在这里插入图片描述


  • 友元虽然有时提供便利可以访问类的私有和保护成员,但是它破坏了封装,不宜多用

3. 类型转换

  • C++支持内置类型隐式转换为类类型对象,需要有相关内置类型的构造函数
  • 构造函数前面+explicit就不支持隐式类型转换了

在这里插入图片描述

  • 1构造了一个A类的临时对象,然后这个临时对象的成员变量_a1 = 1,_a2 = 2,然后再将这个临时变量拷贝构造给aa1,不过编译器优化为直接构造了

  • 常量引用

在这里插入图片描述

  • 用常量100构造一个A类类型的临时对象,该临时对象的成员变量_a1 = 100, _a2 = 2,再将该临时对象绑定在A类常引用上

  • 多参数

在这里插入图片描述

  • 通过{10,20}创建一个A类的临时对象,该临时对象通过对应的构造函数后,其成员变量_a1 = 10,_a2 = 20,再将这个临时对象拷贝构造给aa2

在这里插入图片描述


4. static成员

  • 用static修饰的成员变量,称之为静态成员变量,静态成员变量一定要在类外进行初始化
  • 静态成员变量为所有类对象共享,不属于某个具体的对象,且静态成员变量不存在对象中,而是存放在静态区

在这里插入图片描述


  • 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针
  • 静态成员函数可以访问其他静态成员,但是不能访问非静态的,因为它没有this指针
  • 非静态的成员函数,可以访问任何静态成员变量和静态成员函数

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


  • 突破类域可以访问静态成员变量和静态成员函数,前提是静态成员是公有的
  • 静态成员也是类的成员,同样也受public、private、protected访问限定符的影响
  • 静态成员变量不能再声明位置给缺省值进行初始化,缺省值是给初始化列表的,而静态成员变量不属于某个对象,不走初始化列表

在这里插入图片描述


4.1 练习1(创建对象的个数)

在这里插入图片描述


4.2 练习2(求1+2+…+n)

  • 题目要求不能使用乘除、if、while、for、switch等选择判断循环

在这里插入图片描述


4.3 练习3

在这里插入图片描述


5. 内部类

  • 如果一个类定义在另一个类内部,那么这个类就是“内部类”,内部类是一个独立的类,它只受到外部类的类域和访问限定符影响,所以外部类定义的对象中并不包含内部类
  • 内部类默认是外部类的友元
  • 内部类本质就是一种封装,如果A类和B类相互关联,A类实现出来主要给B类使用,那么可以将A类设计为B类的内部类,放到private位置,那么A类就是B类的专属内部类,其他地方也用不了

在这里插入图片描述


6. 匿名对象

  • 用类型(实参)定义出来的对象就是匿名对象,而之前定义的类型—对象名,这种是有名对象
  • 匿名对象生命周期只有当前一行,一般定义一个对象临时用一下,就可以定义匿名对象

在这里插入图片描述


7. 对象拷贝时的编译器优化

  • 编译器为了提高程序运行的效率,会对传值传参和传参作出部分优化,减少对应的拷贝
  • 优化场景1

在这里插入图片描述


  • 优化场景2

在这里插入图片描述


  • 优化场景3

在这里插入图片描述


  • 临时对象具有常性

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值