本篇博客对类和对象知识体系进行进一步完善
一、构造函数补充——初始化列表
1.初始化列表:成员变量不在构造函数体内初始化,在初始化列表处进行初始化
2.每个成员变量在初始化列表中只能出现一次,语法上:初始化列表是每个成员变量定义+初始化的地方
3.必须在初始化列表初始化的成员
引用成员变量,const成员变量,没有默认构造的类类型变量
4.C++11支持在成员变量声明的位置给缺省值,缺省值主要给没有显式写在初始化列表中的成员用
不管有没有显式写,成员变量都会走初始化列表
5.尽量使用初始化列表初始化,原因如下
不管这个成员在不在初始化列表里面,它的初始化都需要经过初始化列表,区别就是我们看不看得见而已
6.初始化列表中按照成员变量在类中声明顺序初始化
声明顺序:_a2先声明,因此先初始化,此时_a1还是随机值,因此_a2被初始化为随机值
二、类型转换
1.C++支持内置类型隐式转换为类类型的对象,要求要有相关内置类型为参数的构造函数
2.构造函数前面加上explicit,这个类就不支持隐式类型转换
三、static成员
1.静态成员变量:用static修饰的成员变量,一定要在类外初始化
2.静态成员变量被当前类的所有对象共享,存放在静态区。不属于某个具体对象,也不存在对象中
3.静态成员函数:用static修饰的成员函数,没有this指针=>不能访问非静态的成员,只能访问静态成
4.突破类域就可以访问静态成员,访问方式:类名::静态成员or对象.静态成员
5.静态成员也受到public,protected,private访问限定符限制
6.静态成员变量不能在声明位置给缺省值初始化(静态成员变量不走初始化列表)
四、友元
1.友元:提供突破类访问限定符的方式,分为友元函数和友元类
2.友元函数仅仅是一种声明,它不是类的成员函数
3.友元函数可在类的任何地方声明,不受类访问限定符限制
4.一个函数可以是多个类的友元函数(就像一个人可以成为多个人的朋友)
5.友元类中的成员函数都是另一个类中的友元函数,都可以访问另一个类中的私有和保护成员
6.友元类的关系是单向的,比如A类是B类的友元,但B类不是A类的友元
7.友元类关系不能传递
8.友元提供便利,但会增加耦合度,不建议多用
五、内部类
1.定义:一个类定义在另一个类的内部。内部类是一个独立的类,只是受外部类类域限制和访问限定符限制——外部类定义的对象中不包含内部类
2.内部类默认是外部类的友元类
3.内部类本质是一种封装,如果A和B紧密关联,且A实现出来主要给B用,就可以把A设计为B的内部类。如果A放到private/protected位置,就成为了B的专属内部类
- OJ题:求1+2+3+…+n
思路:调用n次构造函数,每次调用n++即可。本题用到了static成员变量和内部类进行解决
class Solution
{
public:
class Sum//内部类
{
public:
Sum()//构造函数
{
_n+=_i;
_i++;
}
};
static int _n;
static int _i;
int Sum_Solution(int n)
{
Sum arr[n];//此处会调用n次构造函数,每调用一次_n就++
return _n;
}
};
int Solution::_n = 0;
int Solution::_i = 1;
六、匿名对象
1.匿名对象生命周期只在当前一行,如果定义一个临时对象用一下就可以这么做
七、对象拷贝时的编译器优化
1.编译器为了尽可能提高效率,在不影响正确性的前提下会尽可能减少传参和传返回值中的拷贝
2.当前主流编译器:会对连续拷贝进行合并优化,不同编译器不同