为什么重载运算符时需要友元关键字<<

Why is friend keyword required when overloading operator<<?

本文关键字:关键字 友元 重载 运算符 为什么      更新时间:2023-10-16

在下面的示例中,我的所有成员都是公开的,所以我不明白为什么我仍然需要添加friend关键字。而且,这种方法属于Point实例,所以我也不明白为什么我应该通过const Point% p来引用我的属性。在重载+中,仅接收外部实例。

#include <iostream>
struct Point {
    int x, y;
    Point(int x, int y): x(x), y(y) {};
    Point operator+(const Point& other) const {
        return Point(x + other.x, x + other.y);
    }
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        return os << "(" << p.x << "," << p.y << ")";
    }
};
int main() {
    Point p = Point(4,7) + Point(8,3);
    std::cout << p << std::endl;
}

在这种情况下,像这样的类似问题并没有真正的帮助。

不,您不必让这里的流插入器成为朋友。问题是代码在类定义中定义了插入器。没有任何修饰,它将是一个普通的成员函数,调用它将是一个语法噩梦。你可以让它成为static成员,但这有悖常理。friend使其工作的原因是一个副作用:将其标记为friend将其定义推到类定义之外。因此,与其使用 friend,只需在类定义之外定义它。

#include <iostream>
struct Point {
    int x, y;
    Point(int x, int y): x(x), y(y) {};
    Point operator+(const Point& other) const {
        return Point(x + other.x, x + other.y);
    }
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
    return os << "(" << p.x << "," << p.y << ")";
}
int main() {
    Point p = Point(4,7) + Point(8,3);
    std::cout << p << std::endl;
}