【发布时间】:2013-11-21 07:14:28
【问题描述】:
在类内定义友元函数与在类内声明和在类外定义有什么区别。还有为什么可以将定义放在类中,因为友元函数不是类的成员。
【问题讨论】:
-
@RogerRowland 如果这是重复的,我喝醉了。
-
@rightfold "可能重复",所以你可能喝醉了 ;-)
标签: c++
在类内定义友元函数与在类内声明和在类外定义有什么区别。还有为什么可以将定义放在类中,因为友元函数不是类的成员。
【问题讨论】:
标签: c++
类内定义的友元函数只有在从类外调用时才能通过 ADL 查找。即使没有 ADL,也可以找到在类之外定义的函数。
【讨论】:
operator== 定义为类中的朋友,当它的两个参数都需要隐式转换时,编译器找不到它......
只要在类中声明友元函数(它必须是),它的声明在哪里都没有关系。
此外,在类中定义 friend 函数也会隐式生成函数 inline。
另外(来自 C++11 规范,§11.3/7):
类中定义的友元函数在 定义它的类。类外定义的友元函数不是
【讨论】:
以下关于会员访问的内容有微妙的含义。
C++11 §11.4/5
类中定义的友元函数在 定义它的类。在外部定义的友元函数 类不是 (3.4.1)。
自 C++17 §14.3/7 起仍存在
这样的函数隐含地是一个内联函数 (10.1.6)。一个朋友 类中定义的函数在类的(词法)范围内 它是定义的。在类外定义的友元函数是 不是 (6.4.1)。
考虑来自cppreference [Friend 函数定义] 的简化示例,其中f1 查找类静态成员,f2 查找全局变量。
int i = 3;
struct X {
friend void f1(int x) {
i = x; // finds and modifies X::i
}
friend inline void f2(int);
static const int i = 2;
};
inline void f2(int x) {
i = x; // finds and modifies ::i
}
当然这不会影响友元功能的设计设计。选择之间的主要考虑因素是名称查找的差异,正如the other 答案中已经提到的那样。不要忘记f2 的内联以匹配默认隐含的f1。
【讨论】:
一个函数可以定义在一个类的友元声明中,如果并且 仅当类是非本地类时,函数名是 不合格,并且该函数具有命名空间范围。这样的功能是 隐式内联。类中定义的友元函数在 定义它的类的(词法)范围。朋友功能 类外定义的不是。
C++11,[class.friend],¶6-7
【讨论】:
如果你在类里面定义它是内联的,如果它在外面就不是。
【讨论】:
Friend 方法总是 inline。
在类中定义友元函数是不合适的。
我们使用友元函数将类的私有成员的访问权限授予函数。
如果我们在类中定义友元函数,那么它就成为类的数据成员,我们知道自己类的数据成员可以访问其私有成员。
所以如果你真的想在 C++ 中使用友元概念,那么在私有类之外声明它。
【讨论】:
friend 方法。