友元说明符在c++中的工作原理

How friend specifier does work in c++?

本文关键字:工作 说明符 c++ 友元      更新时间:2023-10-16

考虑以下代码:

#include <stdio.h>
class A
{
    friend void foo(){ printf("%dn",_a); }
public:
    A(int);
private:
    static const int _a=5;
};
class B
{
    friend void foo(){ printf("%dn",_a); }
private:
    static const int _a=6;
};
int main()
{
    foo();
}

编译后,我有以下错误:

an_test.cpp:14:14: error: redefinition of ‘void foo()’
an_test.cpp:5:14: error: ‘void foo()’ previously defined here
an_test.cpp: In function ‘int main()’:
an_test.cpp:21:6: error: ‘foo’ was not declared in this scope
make: *** [an_test.o] Error 1

我认为用友元说明符定义的函数是外部链接。那么为什么an_test.cpp:21:6: error: ' foo '没有在这个作用域中声明呢?

我发现了一些关于c++友函数的信息,可以帮助您了解错误发生的原因:

c++友元函数

注意:

类的友元函数定义在类的作用域之外,但是它有权访问所有私人和受保护的成员类。尽管好友功能的原型出现在类定义中,友元不是成员函数。朋友可以是函数、函数模板、成员函数或一个或多个类模板,在这种情况下,整个类及其所有成员都是朋友。

我想你把链接与作用域混淆了。在您的代码中,两个foo()定义的作用域都在它们各自的类中,因此main()无法看到它们的定义。

如果你想让foo()main()中可见,你需要将它的声明移到外面,并在类中做一个friend声明。

#include <stdio.h>
class A
{
    friend void foo(A a);
    public:
    A(int) {}
    private:
    static const int _a=5;
};
void foo(A a){ printf("%dn",a._a); }
int main()
{
    foo(A(5));
}

下面也可以,定义在里面,声明在外面。

#include <stdio.h>
class A
{
friend void foo(A a){ printf("%dn",a._a); }
public:
    A(int) {}
private:
    static const int _a=5;
};
 void foo(A a);

int main()
{
    foo(A(5));
}

我想这个关于朋友范围的链接可以回答你的问题

c++中的友元作用域

"Foo是A的朋友"并不意味着"Foo"是"An_test"的朋友