在cpp学习初期大多是通过博客文章以及视频教程等途径学习,但示例总是最基础的那两种写法,今天发现了一种c++少见的友元写法,并对函数进行了一个重新理解,尝试着写出了一个实例。

class A
{
    int a_;
    friend void fun(A a)
    {
        a.a_;
    }
};

这个函数看上去很像一个该类的成员函数,在众多学习资料中友元函数和友元类的实例并没有出现过该种情况,于是我翻阅了cppreference的friend参考页,其中给出了一个示例

class X
{
    int a;
 
    friend void friend_set(X& p, int i)
    {
        p.a = i; // this is a non-member function
    }
public:
    void member_set(int i)
    {
        a = i; // this is a member function
    }
};

看样子像是在一个成员函数前添加friend时,将函数就会从成员函数变为全局函数。但实际上我们只是将一个友元函数的定义内联进了类中。

但为什么不将这个函数写在全局空间而是内联到类中,而且可能还会看错成成员函数的问题呢?

一般这个内联友元汗水定义中,至少有一个形参为该类型,这样函数可以直接访问该类型中的私有成员,看起来就像是成员函数一样,但它实际是一个全局函数。可以直接调用这个函数并传参,因c++支持函数重载,所以这么写其实是让某个全局函数有自己的重载版本,是一种类似模板特化的实现。