目录
1.再探构造函数
(1).之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有一种方式,就是初始化列表,初始化列表的使用方式是以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
class Date
{
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
(2).每个成员变量在初始化列表中只能出现一次(只能初始化一次),语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。
*const 变量的初始化必须在定义的时候就初始化,且必须在初始化列表中初始化。
*引用也必须在定义的时候就初始化,也必须在初始化列表中才能初始化。
*没有合适的默认构造函数可用的类,也必须在初始化列表中才能初始化。
class Time
{
public:
//无默认构造函数
Time(int n)
:_hour(n)
{}
private:
int _hour;
};
class Date
{
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
,_n(666)//重点
,_ref(year)//重点
,_t(1)//重点
{}
private:
int _year;
int _month;
int _day;
const int _n;//必须在初始化列表中才能初始化(必须初始化常量限定类型的对象)
int& _ref;//必须在初始化列表中才能初始化(必须引用初始化)
Time _t;//必须在初始化列表中才能初始化(没有合适的默认构造函数可用)
};
(3).C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的。
class Date
{
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
{}
private:
//这里是声明 等号后面是缺省值不是定义
int _year = 1;
int _month = 1;
int _day = 1;
};
(4).尽量使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译错误
思维导图:
1.在初始化列表初始化的成员
2.没有在初始化列表的成员
a.声明的地方有缺省值
b.声明的地方无缺省值
A:内置类型:不确定,看编译器,大多是随机值
B:自定义类型:调用默认构造,没有就报错。
(5).初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持一致。
2.类型转换
(1).C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。
(2).构造函数前面加explicit就不再支持隐式类型转换
3.static成员
(1).用static修饰的成员变量,称之为静态成员变量,静态成员变量一定要在类外进行初始化。
class Date
{
public:
private:
static int _a;//不在对象中存储,在静态区存储
};
int Date::_a = 100;
(2).静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。
(3).用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
class Date
{
public:
static int geta()
{
return _a;
}
private:
static int _a;//不在对象中存储,在静态区存储
};
int Date::_a = 100;
int main()
{
cout << Date::geta() << endl;
return 0;
}
(4).非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
(5).突破类域就可以访问静态成员,可以通过类名::静态成员 或者 对象.静态成员 来访问静态成员变量和静态成员函数。
(6).静态成员也是类的成员,受public、protected、private 访问限定符的限制。
(7.)静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。
4.友元 friiend
(1).友元分为:友元函数和友元类,在函数声明或者类声明的前面加friend,并且把友元声明放到一个类的里面。
(2).外部友元函数可访问类的私有和保护成员,友元函数仅仅是一种声明,他不是类的成员函数。
(3).友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
(4).一个函数可以是多个类的友元函数。
(5).友元类中的成员函数都可以是另一个类的友元函数,都可以访问另一个类中的私有和保护成员。
(6).友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。
(7).友元类关系不能传递,如果A是B的友元, B是C的友元,但是A不是B的友元。
(8).有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。
本篇完