1.初始化列表
以一个冒号开始,接着是一个以逗号分割的数据成员列表,每个成员变量后面跟一个放在括号中的初始值或表达式
只能通过初始化列表的几种情况
1.对没有默认构造函数的自定义类型
没有默认构造函数时内部初始化时的结果
当自定义类型存在默认构造函数的时候可以使用如上的初始化方式
使用初始化列表对没有默认构造函数的自定义类型初始化,实际上初始化列表就是调用的自定义类型的构造函数
2.const 成员变量必须在初始化列表初始化
const成员变量只有一次赋值的机会,智能在定义的时候初始化。
3.引用成员变量必须在初始化列表初始化
引用与const一样,都需要在定义的时候初始化,所以也只能在初始化列表初始化
推荐使用初始化列表初始化
class A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print() {
cout<<_a1<<" "<<_a2<<endl;
}
private:
int _a2;
int _a1;
};
int main() {
A aa(1);
aa.Print();
}
这段代码的结果是什么?-----1,随机值
因为成员变量的声明顺序才是他的定义顺序,a2先被a1初始化成随机值,a1在被初始化成1
2.匿名对象
Date(2020,4,25);
没有名字的对象,生命周期只有这一行,这一行结束就被析构。
3.explicit关键字
单参数的构造函数在定义的过程中存在隐式类型转换
当有这样一个日期类时
class Date
{
Date(int year)
:_year(year)
{
}
//explicit Date(int year)
//:_year(year)
//{
// }用explicit关键字修饰构造函数,禁止隐式类型转换
private:
int _year;
};
int main()
{
Date d1=2022;//发生了隐式类型转换,会先构造+拷贝构造---》编译器将其优化成了直接构造
//Date &d2=2022;的时候会报错
const Date& d2 = 2022; //可以,因为临时变量具有常性
return 0;
}
4.静态成员
用static修饰的成员变量叫做静态成员变量,静态成员变量被整个类所拥有,不属于某个对象,存储在静态区。
静态成员变量必须在类外面定义,因为静态成员变量不存在于初始化列表中。
静态成员可以通过域名::成员名或者对象.成员名来访问,但访问同样受到访问限定符的限制。
static 修饰的成员函数叫做静态成员函数,静态成员函数没有this指针,只能访问静态成员变量,但非静态成员函数可以访问静态成员变量。
5.友元
5.1友元函数可以访问类的私有成员,他是定义在类外面的函数,友元函数的声明需要用到friend关键字
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明
一个函数可是是多个类的友元
友元函数与普通函数的调用相同
5.2友元类
友元是单向的并且不具有传递性
5.3内部类
一个类定义到另一个类的里面,那他就是内部类,内部类天生就是外部类的友元