类和对象(8):explicit,static成员,友元,内部类

一、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的初始化结果是什么?

类和对象(8):explicit,static成员,友元,内部类_第1张图片

构造函数不仅可以构造与初始化对象,对于1. 单个参数 2. 全缺省 3. 除第一个参数无默认值外其余均有默认值的构造函数,还具有类型转换的作用。

explicit修饰构造函数,将会禁止构造函数的默认转换。

类和对象(8):explicit,static成员,友元,内部类_第2张图片

二、static成员

2.1 概念

声明为static的类成员,称为类的静态成员(静态成员变量或静态成员函数)静态成员变量一定要在类外初始化

class A
{
private:
	static int _a;// 声明
};

int _a = 0;// 初始化

2.2 特性

  1. 静态成员所有类对象共享,存在静态区。

  2. 静态成员变量必须在类外初始化,初始化时不加static

  3. 类静态成员可用**类名::静态成员** 或 **对象.静态成员**来访问。

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() 为匿名对象,当前语句结束后自动销毁。

  1. 类静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  2. 静态成员也是类的成员,同样受访问限定符的限制
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:

  1. 友元函数不能用const修饰

  2. 友元函数可以在类定义的任何位置声明,不受访问限定符限制

  3. 一个函数可以是多个类的友元函数。

  4. 友元函数的调用与普通函数相同。

3.2 友元类

友元类的所有成员函数,都是另一个类的友元函数,可以访问另一类的私有成员。

  1. 友元关系是单向的,不具备交换性。
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;
}
  1. 友元关系不能传递

B是A的友元,C是B的友元,但C和A没有友元关系。

四、内部类

4.1 概念

存在类A、B,如果B定义在A的内部,B称为A的内部类

内部类是一个独立的类,不属于外部类不能通过外部类的对象访问内部类的成员

PS: 内部类就是外部类的友元类,外部类不是内部类的友元。

4.2 特性
  1. 内部类可以定义在外部类的任何位置。
  2. 内部类可以直接访问外部类static成员,不需要使用外部类的 类名对象
  3. sizeof(外部类)=外部类,与内部类无关

你可能感兴趣的:(C++,开发语言,c++,1024程序员节)