一、初始化列表:以一个冒号开始,接着以一个逗号分割的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。如下格式:
class Date
{
public:
Date (int year,int month,int day)
{
:_year(year)
,_month(month)
,_day(day)
}
private:
int _year;
int _month;
int _day;
};
为什么要初始化列表呢?类中的有些成员变量必须借助初始化列表,有些变量借助初始化列表效果更好。如类中的引用成员变量、const 成员变量,由于他们只有一次初始化的机会,所以引用成员变量只能在定义的地方初始化,const成员变量必须在定义的地方初始化,而类中的自定义类型成员没有构造函数时,此时可借助初始化列表初始化自定义类型成员;如果有构造函数,在构造函数{}上面写自定义类型成员的初始化列表,则先会执行自定义类型成员的初始化列表,再执行构造函数{}内部的内容。建议能使用初始化列表就使用初始化列表初始化,使用初始化列表基本上没有什么问题,初始化列表的初始化顺序是按照申明的顺序来的,类中的内置类型的缺省实际上是给初始化列表的,初始化列表无法初始化类中的静态成员,初始化列表可以认为是类中成员变量定义的地方
二、explicit:修饰构造函数,禁止类型转换
explicit Date(int year)
:_year(year)
{}
int main()
{
Date d1(2022);//直接调用构造函数
Date d2 = 2022;//构造+拷贝构造+优化=>直接调用构造.加了explicit后此句执行不通
构造+拷贝构造+优化=>直接调用构造 中的构造 指用2022构造一个Date(int year),再把这个构造拷贝给d2
三、隐式类型转换
int i = 10;
double d = i;//把int(i)->double(d)叫隐式类型转换,其实是把int转换成中间变量double,再把中间变量double转换成double,其中中间变量具有常属性,因此d 的double要用const修饰,最终为:const double d = i
四、匿名转换:生命周期只有一行
正常书写:Date d3(2022)
匿名对象:Date(2022)//生命周期只有一行。所谓匿名对象其实就是把类型定义的变量给隐藏起来了(或者认为没书写这个变量)
五、static:
声明为static的类成员称为类的静态成员,用static修饰的类的成员变量称为类的静态成员变量,用static修饰的类的成员函数,称为类的静态成员函数,类的静态成员变量一定要在类外进行初始化。类的静态成员变量无法用初始化列表初始化,如private中的静态成员无法给缺省值,因为缺省值是给初始化列表的=>总结:
类的静态成员:static修饰的函数、static修饰的声明。它们都叫类的静态成员,类的静态成员由它俩组成
static修饰的函数 叫类的静态成员函数;
static修饰的声明 定义了一个变量叫 类的静态成员变量
class A
{
public:
A() { ++_scount; }
A(const A& t) { ++_scount; }
~A() { --_scount; }
static int GetACount() { return _scount; }
private:
static int _scount;
};
int A::_scount = 0;//类外面初始化
void TestA()
{
cout << A::GetACount() << endl;
A a1, a2;
A a3(a1);
cout << A::GetACount() << endl;
}
类的静态成员特征:
1)一个类如果定义了多个变量(如Date A,B,C),那么这个类的静态成员在这些变量中是共用的
2)类中的静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
3)类静态成员即可用类名::静态成员或者对象.静态成员来访问
4)类的静态成员函数没有隐藏的this指针,不能任意访问非静态成员
5)类中的静态成员也是类的成员,受public、protected、private访问限定符的限制
六、友元 :一种突破封装的方式,借助友元可以从类外访问类里面。友元有关的主要关注 友元函数,友元类,内部类。
友元函数:可以直接访问类的私有成员,他是定义在类的外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。
说明:
友元函数可访问类的私有和保护成员,但不是类的成员函数;
友元函数不能用const修饰;
友元函数可以在类定义的任何地方声明,不受类访问限定符限制;
一个函数可以是多个类的友元函数;
友元函数的调用与普通函数的调用原理相同。
友元类:将一个类B变成另一个类A的友元(函数),这个类B的定义不在A里面
说明:
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员;
友元关系是单向的,不具有交换性;
友元关系不能传递;(如,如果C是B的友元,B是A的友元,则不能说明C是A的友元。)
友元关系不能继承
内部类:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。
说明:
内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任
何优越的访问权限;
内部类就是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部
类的友元;
内部类可以定义在外部类的public、protected、private都是可以的;
注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名;
sizeof(外部类)=外部类,和内部类没有任何关系。
class A
{
public:
class B
{
}
private:
}
B受A的类域限制,B定义变量前必须写A::,B也受A的访问限定符限制;
B天生是A的友元。