一、explicit
class Date { public:Date(int year = 2023, int month = 1, int day = 1):_year(year),_month(month),_day(day){}private:int _year;int _month;int _day; };int main() {// Date d1(1); // 这是正常初始化Date d1 = 1;return 0; }
不妨猜测一下,d1的初始化结果是什么?
构造函数不仅可以构造与初始化对象,对于1. 单个参数 2. 全缺省 3. 除第一个参数无默认值外其余均有默认值的构造函数,还具有类型转换的作用。
用explicit
修饰构造函数,将会禁止构造函数的默认转换。
二、static成员
2.1 概念
声明为static的类成员,称为类的静态成员(静态成员变量或静态成员函数)。静态成员变量一定要在类外初始化。
class A
{
private:static int _a;// 声明
};int _a = 0;// 初始化
2.2 特性
-
静态成员为所有类对象共享,存在静态区。
-
静态成员变量必须在类外初始化,初始化时不加
static
。 -
类静态成员可用**
类名::静态成员
** 或 **对象.静态成员
**来访问。
class A
{
public:static int GetCount_top(){_top++;return _top;}A():_a1(1){}private:int _a1;static int _top;
};int A::_top = 0;int main()
{A a1;cout << a1.GetCount_top() << endl; // 对象.静态成员cout << A().GetCount_top() << endl;// A() 为匿名对象cout << A::GetCount_top() << endl; // 类名::静态成员return 0;
}
A()
为匿名对象,当前语句结束后自动销毁。
- 类静态成员函数没有隐藏的this指针,不能访问任何非静态成员。
- 静态成员也是类的成员,同样受访问限定符的限制。
int main()
{A a1;cout << a1._top << endl; // error C2248: “A::_top”: 无法访问 private 成员(在“A”类中声明)return 0;
}
三、友元
友元是一种突破封装的方式,部分场景能提供便利。但友元会增加耦合度,不宜多用。
3.1 友元函数
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1):_year(year), _month(month), _day(day){}friend ostream& operator<<(ostream& out, const Date& d); // 友元函数friend istream& operator>>(istream& in, Date& d);private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "-" << d._month << "-" << d._day;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
友元函数可以直接访问类的私有成员,它是定义在类外部的函数,不是类的成员函数;需要在类的内部声明,声明时加friend
。
PS:
-
友元函数不能用
const
修饰。 -
友元函数可以在类定义的任何位置声明,不受访问限定符限制。
-
一个函数可以是多个类的友元函数。
-
友元函数的调用与普通函数相同。
3.2 友元类
友元类的所有成员函数,都是另一个类的友元函数,可以访问另一类的私有成员。
- 友元关系是单向的,不具备交换性。
class A {friend class B;// B是A的友元类,但A不是B的友元类 public:A():_a(1){} private:int _a; };class B { public:B():_b(1){A a1;} private:int _b; };int main() {B b1;return 0; }
- 友元关系不能传递。
B是A的友元,C是B的友元,但C和A没有友元关系。
四、内部类
4.1 概念
存在类A、B,如果B定义在A的内部,B称为A的内部类。
内部类是一个独立的类,不属于外部类,不能通过外部类的对象访问内部类的成员。
PS: 内部类就是外部类的友元类,外部类不是内部类的友元。
4.2 特性
- 内部类可以定义在外部类的任何位置。
- 内部类可以直接访问外部类static成员,不需要使用外部类的 类名 或 对象。
sizeof(外部类)
=外部类
,与内部类无关。