一、初始化列表
1.初始化列表的定义
初始化列表是构造函数中以冒号开始,中间用逗号分隔成员变量初始化表达式的列表。
2.初始化列表的用法
class date
{
public:
date()
:_year(2024),
_month(1),
_day(1)
{
}
private:
int _year;
int _month;
int _day;
};
在构造函数后面用冒号开始,成员变量后括号内是初始化的值,用逗号分隔。
注意点:
1.初始化列表与构造函数并不冲突,事实上无论你写不写初始化列表,调用构造函数时编译器都会走一遍初始化列表,并且对自定义类型调用它的构造函数进行初始化。
class date
{
public:
date()
:
_year(2024),
_month(1)
{
_day = 6;
}
private:
int _year;
int _month;
int _day;
};
下面我们并不写包含自定义变量的初始化列表,在默认构造函数中也不对自定义类型的对象赋值
class A
{
public:
A()
{
a = 1;
b = 2;
}
int a;
int b;
};
class date
{
public:
date()
:_year(2024),
_month(1),
_day (1)
{
}
private:
int _year;
int _month;
int _day;
A _t;
};
我们会发现_t中的a,b仍然会被分别初始化为1和2。
2.初始化列表初始化成员变量的顺序是按照成员变量声明的顺序。
class A
{
public:
A(int t)
:b(t),
a(b)
{
}
private:
int a;
int b;
};
int main()
{
A t(3);
return 0;
}
对于上述代码,a的值为随机值,b的值为1。因为初始化列表先用b初始化a,而此时b为随机值,之后才用t初始化b。
3.初始化列表初始化成员变量只能初始化一次,不能重复初始化。
4.成员声明处的缺省值是为初始化列表服务的。
3.初始化列表的意义
因为成员变量的初始化只能在初始化列表中进行(构造函数不能算初始化),所以对于const修饰的成员变量、对某类型引用的成员变量、没有默认构造的自定义类型的成员变量必须使用初始化列表初始化。实际来说,我们应该尽量用初始化列表来初始化成员变量。
二、explicit关键字
隐式类型转换:
当我们用常量来赋值类的时候,会发生隐式类型转换。
class A
{
public:
A(int t)
{
_a = t;
}
private:
int _a;
};
int main()
{
A m = 3;
return 0;
}
编译器会先用3生成一个具有常性的临时变量,再将临时变量拷贝构造给m。
如果类有多个成员变量,可用大括号括起来。
class A
{
public:
A(int x,int y)
{
_a = x;
_b = y;
}
private:
int _a;
int _b;
};
int main()
{
A m = { 1,2 };
return 0;
}
用法:
explicit放在构造函数前,可防止隐式类型转换的发生。
此时会发现编译器报错。
三、友元
1.友元的定义
友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加
以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。
2.友元的用法
对于类中的私有成员,在类外我们无法访问,因此需要友元来帮助我们访问。
2.1 全局函数作友元
在类内声明该全局函数,并在返回值前加上关键字friend,这样全局函数就能访问类内私有成员了。
class date
{
friend void print(date& v);
public:
date()
:
_year(2024),
_month(1),
_day(1)
{
}
private:
int _year;
int _month;
int _day;
};
void print(date &v)
{
cout <<v._year<< "年" << v._month << "月" << v._day << "日" << endl;
}
2.2 类作友元
在类内声名类,并在之前加上关键字friend,这样被声明的类就可以访问该类的私有成员了。
class A
{
friend class B;
public:
A()
{
a = 1;
b = 2;
}
private:
int a;
int b;
};
class B
{
public:
void print()
{
cout << t.a << " " << t.b << endl;
}
private:
A t;
};
2.3 内部类
类中可以定义类,定义的类是独立的类,只受类域和外部类访问权限的限制。
内部类天生就是外部类的友元。
class A
{
private:
int a;
int b;
public:
A()
{
a = 1;
b = 2;
}
class B
{
public:
void print(A& v)
{
cout << v.a << " " << v.b << endl;
}
private:
int b;
};
};
四、C++类中static关键字
1.static修饰成员变量
static修饰成员变量时,该成员变量储存区域由栈区改为静态区,生命周期延长,该类实例化的所有对象共用该成员变量。
static修饰的成员变量初始化在类外部。
class A
{
public:
A()
{
b = 2;
}
private:
static int a;
int b;
};
int A::a = 1;
2.static修饰成员函数
static修饰成员函数时,该成员函数没有this指针,只能访问该类的静态成员变量。
class A
{
public:
static void print()
{
cout << a << endl;
}
private:
static int a;
};
int A::a = 1;