C++的友元函数

什么是友元函数
①。一个类的私有数据成员通常只能由类的函数成员来访问,而友元函数可以访问类的私有数据成员,也能访问其保护成员。
②。友元函数不是任何类的成员函数,友元关系是指定的,不是获取的,如果让类B成为类A的友元类,类A必须显式声明类B为自己的友元类。
使用友元函数的好处
使用友元函数可提高性能,如:用友元函数重载操作符和生成迭代器类
用友元函数可以访问两个或多个类的私有数据,较其它方法使人们更容易理解程序的逻辑关系
使用友元函数的注意点
①。类的友元函数在类作用域之外定义
②。由于友元函数不是任何类的成员函数,所以不能用句柄(对象)加点操作符来调用
③。public, private, protected成员访问符与友员关系的声明无关,因此友元关系声明可在类定义的任何位置,习惯上在类定义的开始位置
④。友元关系不满足对称性和传递性,如果一个友元函数想与两个或更多类成为友元关系,在每个类中都必须声明为友元函数。同样,如果一个类想拥有多个友元函数,那么需要对每个友元函数都声明。

NOTE

友元
类的主要特点之一是数据隐藏和封装,即类的私有成员(或保护成员)只能在类定义的范围内使用,也就是说私有成员只能通过他的成员函数来访问。但是,有时为了访问类的私有成员而需要在程序中多次调用成员函数,这样会因为频繁调用带来较大的时间和空间开销,从而降低程序的运行效率。
为此,C++提供了一种访问私有成员的途径,在不放弃私有成员数据安全性的情况下,使得一个普通函数或者类的成员函数可以访问到封装于某一类的信息(包括公有,私有,保护成员),在C++中友元作为实现这个要求的辅助手段。C++中的友元为数据隐藏这堵不透明的墙开了一个小孔,外界可以通过这个小孔窥视类内部的秘密,友元是一扇通向私有成员的后门。
友元包括友元函数和友元类,下面分别予以介绍。

友元函数:
友元函数既可以是不属于任何类的成员函数,也可以是另一个类的成员函数。友元函数不是当前类的成员函数,但它可以访问该类所有的成员,包括私有成员,保护成员和公有成员。
在类中声明友元函数时,需在其函数名前加上关键字friend。此声明可以放在公有部分,可以放在保护部分和私有部分。友元函数可以定义在类内部,也可以定义在类外部。
①。友元函数虽然可以访问类对象的私有成员,但它毕竟不是成员函数。因此,在类的外部定义友元函数时,不必像成员函数那样,在函数名前加上"类名::",
②。因为友元函数不是类的成员,所以它不能直接访问对象的数据成员,也不能通过this指针访问对象的数据成员,它必须通过作为入口参数传递进来的对象名(或对象指针,对象引用)来访问该对象的数据成员。
③。由于一个友元函数可能属于多个不同的类,所以在访问时,必选加上对象名。
④。友元提供了不同类的成员函数之间,类的成员函数与一般函数之间进行数据共享的机制。尤其当一个函数需要访问多个类时,友元函数非常有用,普通成员函数只能访问其所属的类,但是多个类的友元函数能够访问相关的所有类的数据。

被定义成类的友元函数后,它能够访问类的所有数据(包括私有数据)。应该指出的是,引入友元提高了程序运行效率,实现了类之间的数据共享并方便了编程。但是,声明友元函数相当于在实现封装的黑盒子上开洞,如果一个类声明了许多友元,则相当于在黑盒子上开了很多洞,显然这将破坏数据的隐蔽性和类的封装性,降低了程序的可维护性,这与面向对象程序设计思想是背道而驰的,因此使用友元函数应谨慎。

将成员函数声明为友元函数
除了非成员函数可以作为某个类的友元外,一个类的成员函数也可以作为另一个类的友元,它是友元函数的一种,称为友元成员函数。友元成员函数不仅可以访问自己所在类对象中的私有成员和公有成员,还可以访问friend声明语句所在类对象中的所有成员,这样能使两个类相互合作,协调工作,完成某一任务。
①。一个类的成员函数作为另一个类的友元函数时,必须先定义这个类。如类Student的成员函数为类Score的友元函数,必须先定义类Student。并且在声明友元函数时,要加上成员函数所在类的类名,如:friend void Student::showScore_Student(Score& sc);
②。程序中第四行语句“class Score;”为Score类的提前引用声明,因为函数中将"Score &"作为参数,而Score要在晚一些时候才被定义。

友元类
不仅可以将一个函数声明为一个类的友元函数,而且可以将一个类(如Y类)声明为另一个类(如X类)的友元,这时,Y类就是X类的友元。友元类的说明方法是在另一个类声明中加入语句"friend 类名:",此语句可以放在公有部分也可以放在私有部分或保护部分。声明友元类的一般形式为:

friend 类名;
例如:
class Y{
   ...
};
class X{
   ...
   friend Y;
   ...
};

①。友元关系是单向的,不具有交换性。若声明了类X是类Y的友元(即在类Y定义中声明X为friend类),不等于类Y一定是X的友元,这要看在类X中是否有相应的声明。
②。友元关系也不具有传递性,若类X是类Y的友元,类Y是类Z的友元,不一定类X是类Z的友元。如果想让类X是类Z的友元类,应在类Z中做出声明。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值