友元
概述:C++ 友元
[toc]
友元
C++ 提供了另外一种形式的访问权限:友元。友元有3种:
- 友元函数
- 友元类
- 友元成员函数
通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。
为何需要友元
在为类重载二元运算符时(带两个参数的运算符)常常需要友元。将 Time 对象乘以实数就属于这种情况。
下面的语句:
1 |
|
将被转换成:
1 |
|
但下面的语句又如何呢?
1 |
|
从概念上说,2.75*B
与 B*2.75
相同,但第一个表达式不对应于成员函数,因为2.75不是 Timer 类型的对象。记住,左侧的操作数应是调用对象,但2.75不是对象。因此,编译器不能使用成员函数调用来替换该表达式。
解决这个难题的一种方式是,告知每个人(包括程序员自己),只能按 B*2.75
的格式编写,不能写成2.75*B
。这是一种对服务器友好-客户警惕的(server-friendly, client-beware)解决方案,与OOP无关。
当然,上述的问题也有解决方案——非成员函数。非成员函数不是由对象调用的,它使用的所有值(包括对象)都是显式参数。这样,编译器能够将下面的表达式:
1 |
|
与下面的非成员函数调用匹配:
1 |
|
该函数的原型如下:
1 |
|
对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。而原来的成员函数可以访问类的私有成员,它们被称为友元函数。
创建友元
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字 friend
:
1 |
|
该原型意味着下面两点:
- 虽然
operator*()
函数是在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用; - 虽然
operator*()
函数不是成员函数,但它与成员函数的访问权限相同。
第二步是编写函数定义。因为它不是成员函数,所以不要使用 Time:: 限定符。另外,不要在定义中使用关键字 friend
,定义如下:
1 |
|
总之,类的友元函数是非成员函数,其访问权限与成员函数相同。
友元
https://hodlyounger.github.io/2023/10/27/D_立志博览群书/《C++ primer plus》/第11章 使用类/【CPP】友元/