一、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(外部类)
=外部类
,与内部类无关。