友元函数和声明

friend functions and declarations

本文关键字:声明 函数 友元      更新时间:2023-10-16

我有一个类,它有一个朋友函数,例如,如果标题是:

 class A{
       friend void foo();
       public:
             A(){}
 };
 void foo();

所以我无法得到的是编译器如何处理第二个声明?

我都注意到我可以随心所欲地写它们,没有任何效果,例如

void foo();
void foo();
...

(假设实现在 cpp 文件中)

另外,我找不到标准在哪里说将某个函数声明为朋友也声明函数本身。

如果friend声明是唯一的声明,则该函数将位于周围的命名空间中,但无法通过正常的查找规则找到;它只能通过参数相关查找找到。

在这种情况下,这意味着根本找不到它,因为没有参数;所以你还需要命名空间中的一个声明来使其可访问。

有时你想要这种行为;例如,ADL 可以找到流式处理运算符,而无需在命名空间中声明它:

struct A {
    friend std::ostream & operator<<(std::ostream & s, A const & a) {
        return s << "Hello";
    }
};
A a;
std::cout << a;   // finds the friend function by ADL, based on the argument 'a'

我都注意到我可以随心所欲地写它们,没有任何效果

是的,您可以根据需要多次重复声明。

另外,我找不到标准在哪里说将某个函数声明为朋友也声明函数本身。

无论声明是否包含friend说明符,声明的大多数规范(C++11 条款 7)都是相同的。 7.3.1.2/3 指定名称位于命名空间中,而不是类中,并且还指定查找规则。

friend void foo();

这种清除只是告诉编译器,你在某个地方有一个void foo()函数,并且该函数将能够访问类的所有成员。以及你写了多少次:

void foo();
void foo();

这不会产生影响,因为这是foo()的原型,而不是foo()的定义。在某个地方,您必须编写一个foo()正文,否则对foo()的任何调用都将失败