为什么可以将友元函数定义放在类定义中?

Rik*_*ika 17 c++ operator-overloading friend

是否应该在类之外明确定义朋友函数?
如果是这样,为什么我可以像任何成员函数一样在类定义中声明友元函数?
这是什么 ?
是否仅<适用于某些运营商(如运营商)或是否适用于所有运营商?
如果它适用于所有这些,那么这样做是否有任何不利之处?
应该避免吗?如果是这样的话?

class person 
{
public:
    bool operator<(int num)
    {
        return  x < num ? true : false ;
    }
    bool operator<(person& p)
    {
        return  x < p.x ? true : false ;
    }

    friend bool operator<(int num, person &p)
    {
        return  p.x < num ? true : false ;
    }

    void setX(int num)
    {
        x = num;
    }

private:
    int x;


};
Run Code Online (Sandbox Code Playgroud)

更新:
我不是要求选择非成员运算符重载或成员运算符重载.
我想知道的是:
为什么我们被允许在我们的类定义中移动friend方法的定义?.
它不违反任何事情吗?如果不是,为什么我们会在第一时间有朋友?
我们可以简单地将重载定义为成员函数(我知道成员函数的局限性)但是我说知道这一点,为什么编译器没抱怨我没有在类定义之外定义友元函数,因为它不需要是在它内部(因为它具有类参数)那么为什么我们允许在类定义中定义友元函数?

Ale*_*sie 12

是否应该在类之外明确定义朋友函数?

可以在类声明中定义友元函数.这些函数是内联函数,就像成员内联函数一样,它们的行为就好像它们是在看到所有类成员之后但在类作用域关闭之前(类声明结束)之前立即定义的.在类声明中定义的友元函数不在封闭类的范围内考虑; 他们在文件范围内. 引用

是否仅适用于某些运营商,如<运营商,还是适用于所有运营商?

最好尽量避免使用友元函数,因为它们与您尝试使用私有类作用域相反,主要是"隐藏"变量.如果您的所有功能都是朋友功能,那么使用私有变量有什么用?

仍然有一些常见的运算符通常被声明为友元函数,那些是operator<<operator>>


Bla*_*sco 6

亚历山德鲁·巴巴罗西的答案是正确的。这意味着我们可以在类中声明一个友元函数,它不是成员函数。这可以很好地组织代码。我认为一个例子可以帮助理解它,以防不清楚。

#include <iostream>

class A {
    public:
        A(int val) : val(val) {}
        // The following isn't a member function, it is a friend 
        // function declared inside the class and it has file scope
        friend void draw (A &a) {
            std::cout << "val: " << a.val << "\n";
        }
    private:
        int val;
};

int main() {
    A a(5);
    draw(a); // outputs "val: 5"
    //A::draw(a); // Error: 'draw' is not a member of 'A'
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*ack 4

因为运算符需要知道所使用的表达式右侧的详细信息,所以如果它必须访问驻留在该侧的类型的私有数据,则它需要属于friend该类。

如果您尝试将 anint与 a进行比较person(如您的示例中所示),选择有两个:

  • person您提供从到 的隐式转换int,以便<可以使用它而无需访问任何私有字段。
  • 或者您将运算符声明为friendof person,以便它可以x在比较的右侧进行访问。

  • 如果只有友元声明位于类定义内,而友元函数定义保留在类定义之外,那么这仍然是可能的。 (3认同)