前言:本文章主要用于个人复习,追求简洁,感谢大家的参考、交流和搬运,后续可能会继续修改和完善。
因为是个人复习,会有部分压缩和省略。
一、友元
友元分为友元函数和友元类
想在类外访问类里的私有变量时,有两种方法
1.在想访问的类里再写一个函数,然后在类外调用该函数
2.把类外的要访问的函数在该类里定义成友元函数
在类里的函数前加一个friend就是定义为友元,定义成友元,就能访问其中的数据
当定义A是B的友元,A可以访问B的所有成员,但是B不能访问A的所有成员。
friend class Date
友元不具有传递性,比如C能访问B,B能访问A,但是C是不能访问A的。
平时不建议使用友元
友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用和原理相同友元关系是单向的,不具有交换性。
友元关系不能传递
结论:一般情况下不建议使用友元,友元是一种破坏封装的行为,不到万不得已,不要用
二、初始化列表初始化
初始化分为两种:在函数体内初始化和初始化列表初始化,使用的时候两种都可以,并且混着用也可以。但是要注意:
每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次),但是分开出现可以,比如说上面出现一次,下面出现一次
类中包含引用成员变量、const成员变量、自定义类型成员(该类没有默认构造函数),不能在函数体内初始化,必须放在初始化列表位置进行初始化。
为什么这三类成员不能再函数体内初始化呢?
因为它们必须在定义的时候就初始化。不论是const还是引用,都得在定义的时候就初始化,可以理解成,一个对象的单个成员变量在初始化列表是它定义的阶段。
以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括
号中的初始值或表达式。
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
建议:养成一个好的习惯,类中成员变量声明的顺序和初始化列表出现顺序保持一致
三、
单参数的构造函数,支持隐式类型转换
四、内部类
即在类里定义类
class A
{
private:
//B就叫做A的内部类
static int k;
int h;
public:
class B //B天生就是A的友元
{
public:
void foo(const A& a)
{
cout << k << endl;//OK
cout << a.h << endl;//OK
}
};
};