1.深谈构造函数
1.1初始化列表
在C++类和对象(中)我们谈到构造函数的是对创建的对象的成员变量进行赋初值。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟在一个放在括号中的初始化值或者表达式。
1.2易错点
1.初始化只能初始化一次,即每个成员变量只能在初始化列表中只能出现一次。
2.有三种成员必须在初始化列表位置进行初始化,其他的成员函数可以不在初始化列表初始化。
- 引用成员变量 ---->引用必须在定义的实话初始化
- const成员变量 ---->const限定 的变量在定义的时候必须给定初始值
- 没有默认构造函数的自定义类型---->如下
- 如果自定义类型没有在初始化列表中初始化,且没有默认构造函数,函数会报错。
- 如果自定义类型有默认构造函数,在初始化列表中初始化和在函数体中初始化对比。
1.3成员变量的初始化顺序
1.4explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换作用。
而这种代码的可读性不是很好,用explicit构造函数,将会禁止单参构造函数进行隐式转换。
2 static成员
2.1 概念
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数,静态的成员变量一定要在列外面进行初始化(仅限于静态的私有成员变量在类外面初始化)。
2.2特性
- 静态成员为所在类对象共享,不属于具体的实例,生命周期为整个程序运行周期。
- 静态成员变量必须定义在类外面,定义时不添加static关键字。
- 静态成员即可用类名::静态成员或者对象.静态成员来访问。
- 静态成员函数没有隐藏的this指针,不能访问任何非静态成员。
- 静态成员和类的普通成员一样,也有public、pretected、private3种访问级别,也可以具有返回值。
问题 1:
静态成员函数可以调用非静态成员函数吗?
不可以。静态成员函数属于类本身,不属于任何一个实例化的对象,而非静态函数是属于对象的。静态函数随着类的声明而独立存在,非静态函数只在对象实例化后才存在,也就是说,静态成员函数产生在前,不可能让一个先产生的函数取调用一个后产生的函数。
问题 2:
非静态成员函数能访问静态成员函数吗?
可以,原因和上个问题相反。
2.3 关于静态成员变量定义
面试题:实现一个类,计算程序中创建了多少个类对象
方法:定义一个静态变量,每调用一次构造函数和拷贝构造函数,该变量就++一次。
3.C++11的成员初始化的新玩法
C++11支持非静态成员变量在声明时进行初始化赋值,但是要注意这里不是初始化,这里是给声明的成员变量缺省值。
4.友元
友元分为友元函数和友元类
友元的作用:
提供了一种突破分装的方式,有时提供便利,但是友元会破坏了分装,所以不宜多用。
4.1友元函数
当我们重载刘插入的时候,会存在这么一个问题,如下图:
值得一提的是,友元函数可以直接访问私有成员,它是定义在类外面的普通函数,不属于任何类。但需要在类内部声明,声明时需要加friend关键字。
注意点:
- 友元函数可访问类的私有和保护成员,但是不是类的成员函数。
- 友元函数不能用const修饰。(因为不存在this指针)。
- 友元函数可以在类的任何地方声明,不受类访问限定符的限制。
- 一个函数可以是多个类的友元函数。
- 友元函数的调用与普通函数调用的原理一样。
4.2友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非共有成员。
- 友元关系是单向的,不具有交换性。--->A是B的友元,A中可以访问B的私有成员,但是B不能访问A的。
- 友元关系不能传递。--->A是B的友元,B是C的友元,但是不能说明A是C的友元
5.内部类
5.1概念
如果一个类定义在另一个类的内部,这个类就叫做内部类。此时这个内部类是独立的,它不属于外部类,更改不能通过外部类的对象去调用内部类。外部类对内部类没有任何的访问权限。
注意:
内部类就是外部类的友元,所以内部类可以通过内部类的对象参数访问外部类的所有成员。