friend友元

1.友元函数

在类的内部可以随意访问私有成员,类的外部不能随意访问私有成员,但总会有时候我们想要从类外面访问私有成员,每次专门为得到这个成员变量而写一个函数过于繁琐,直接用友元函数会更加方便。

  友元函数可以 直接访问 类的 私有 成员,它是 定义在类外部 普通函数,不属于任何类,但需要在
类的内部声明,声明时需要加friend关键字。  
当我们试图重载输入输出操作符时,会发现重载的参数很不符合参数传递的顺序。 因为不管怎么传 cout(cin)的 输出(入)流对象和隐含的this 指针在抢占第一个参数的位置 this指针默认是第一个参数也就是左操作 数了。但是实际使用中cout(cin) 需要是第一个形参对象,才能正常使用。所以要将 operator<<和operator>>重载成 全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。
//创建日期类,并声明友元函数
class Date
{
     friend ostream& operator<<(ostream& _cout, const Date& d);
     friend istream& operator>>(istream& _cin, Date& d);
public:
     Date(int year = 1, int month = 1, int day = 1)
     : _year(year)
     , _month(month)
     , _day(day)
     {}
private:
     int _year;
     int _month;
     int _day;
};
//重载后,参数传递顺序符合常规调用
//可能调用多次,故返回值是ostream&(istream&)
ostream&operator<<(ostream&_cout, const Date& d)
{
     _cout << d._year << "-" << d._month << "-" << d._day;
     return _cout; 
}
istream&operator>>(istream&_cin, Date& d)
{
     _cin >> d._year;
     _cin >> d._month;
     _cin >> d._day;
     return _cin;
}

因为需要在类外面定义,它不认识类内部成员,这时候就需要friend友元函数。这样一来,我们就完成了自定义类型的输入和输出。

没有友元函数就无法完成自定义类型的输入输出,或者说,不能很好的完成常规调用,友元提供了一种突破封装的方式,有时提供了便利。这既给我们带来了方便,也存在一些弊端:它增加了耦合度,毕竟每一个使用友元的地方都有可能改变原来的私有成员,频繁的使用只会更加破坏封装,所以 友元不宜多用。
2.友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
class A
{
	friend class B;
public:
	A(int a = 0)
	{
		_a = a;
	}

private:
	int _a;
};
class B
{
public:
	B(int b = 1)
	{
		_b = b;
	}
	void func()
	{
		aa._a++;
	}
private:
	int _b;
	A aa;
};

B是A的友元,B理应能够访问A内部成员,反之,那么A能否访问B内的成员?

友元关系是单向的,不具有交换性。
所以得出,在A内声明B是A的友元类,B可以访问A的成员,但A不能访问B的成员。
类似地,友元关系不能传递
如果 C B 的友元, B A 的友元,则不能说明 C A 的友元。
3.内部类
当一个类中又定义了一个类, 这个内部的类就叫做内部类
内部类就是外部类的友元类 ,参见友元类的定义,内部类可以通过外部类的对象参数来访
问外部类中的所有成员。

友元关系是单向的,所以只能说明内部类是外部类的友元,而不能得到外部类是内部类的友元。因此,外部类是不能随意访问内部类的成员。

另外,在一个类中定义了内部类以后,计算它的大小时,不会计算内部类,因为内部类的存储其实并没有存在外部类中 。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值