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