构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
构造函数体中的语句只能将其称作为赋初值,而不能称作初始化,初始化只能初始化一次,而构造函数体内可以多次赋值。
class Date
{
public:
Date(int year,int month,int day)//初始化
{
_year=year;
_month=month;
_day=day;
}//赋值
private:
int _year;
int _month;
int _day;
};
初始化列表
以一个冒号开始,接着时一个以都好分隔的数据成员列表,每个“成员变量”后面根一个放在括号中的初始值或表达式。
class Date
{
public:
Date(int year,int month,int day):_year(year),_month(month),_day(day){}//初始化列表
private:
int _year;
int _month;
int _day;
};
注意:
1.每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次);
2.类中包含(引用成员变量、const成员变量、自定义类型成员(该类没有默认构造函数)),必须放在初始化列表位置进行初始化;
3.尽量使用初始化列表初始化,因为不管是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化;
4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
class A
{
public:
A(int a):_a1(a),_a2(_a1){}//先初始化_a2时,_a1是随机值,所以_a2输出结果为随机值;
//再初始化_a1时,a=1,所以_a1输出结果为1;
void Print()
{
cout<<_a1<<" "_a2<<endl;
}
private:
int _a2;//成员变量声明的地方,初始化以此为顺序,先初始化_a2,再初始化_1。
int _a1;
};
int main()
{
A aa(1);
aa.Print();
}
explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用。用explicit修饰构造函数,将会禁止单参构造函数的隐式转换,(多个参数不支持隐式类型转换)
构造函数前+explicit:
explicit Date(int year):_year(year){}
static成员 静态成员变量/函数
静态成员为所有类对象所共享,(可以看做类的成员),不属于某个具体的实例;
static成员不会存放在对象中,存放在静态数据区;
static成员必须在类外定义,定义时不加static关键字;
static成员的访问方式:
(1)通过对象访问,对象.static成员,对象指针->static成员
(2)通过类名访问,类名::static成员
(3)普通成员不能通过类名访问
静态成员函数也有两种访问形式,同成员变量;
static成员函数只能访问static成员函数,不能访问非静态成员函数;
static成员函数没有隐藏的this指针;
访问static成员时,对象可能不存在;
静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值;
静态成员函数不能调用非静态成员函数,没有this指针传给非static成员函数;(局部对象可以调用)
非静态成员函数可以调用类的静态成员函数;
C++11的成员初始化方式
相当于一个缺省值。给声明的成员变量缺省值。
友元(friend)
友元分为:友元函数和友元类。
友元提供了一种突破封装的方式,有时候提供了便利,但是会增加耦合度,破坏了封装,所以不宜多用。
友元函数
友元函数可以访问类的私有和保护成员,仍然是一个普通函数,不是类的成员函数;
在类外定义;
friend在声明的时候使用,定义时不需要;
友元函数不能用const函数修饰;
友元函数可以在类的任何地方声明,不受类访问限定符限制;
一个函数可以时多个类的友元函数;
class Date
{
friend ostream& operator<<(ostream& _cout,const Date& d);
friend istream& operator>>(istream& _cin,Date& d);
public:
Date(int year,int month,int day):_year(year),_month(month),_day(day){}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout,const Date& d)
{
_cout<<d._year<<"-"<<d._month<<"-"<<d._day<<endl;
return _cout;
}
istream& operator>>(istream& _cin,Date& d)
{
_cin>>d._year;
_cin>>d._month;
_cin>>d._day;
return _cin;
}
int main()
{
Date d;
cin>>d;
cout<<d<<endl;
return 0;
}
友元类
友元类的所有成员函数都可以时另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的;
友元关系不能传递;
内部类
内部类是外部类的友元类;
内部类可以访问外部类的所有成员:
普通成员:通过对象访问;
静态成员:可以直接访问,不需要加对象(可以但不需要);
注意:如果是普通的友元函数,静态成员还是需要通过对象或者类名访问;
内部类独立于外部类,不属于外部类;
外部类不能访问内部类的私有成员;