在 C++ 中重载 << 运算符需要朋友

Overloading << operator in C++ requires friend

我正在学习 C++,特别是运算符重载。

我有如下一段代码:

#include <iostream>
#include <string>

using namespace std;

class Vector2
{
private:
    float x, y;

public:
    Vector2(float x, float y)
        : x(x), y(y) {}
    Vector2 Add(const Vector2& other) const;
    Vector2 operator+(const Vector2& other) const;
    Vector2 operator*(const Vector2& other) const;
    friend ostream& operator << (ostream& stream, const Vector2& other);
    Vector2 Multiply(const Vector2& other) const;
};

ostream& operator << (ostream& stream, const Vector2& other)
{
    stream << other.x << ", " << other.y;
    return stream;
}

Vector2 Vector2::Add(const Vector2& other) const
{
    return Vector2(x + other.x, y + other.y);
}

Vector2 Vector2::operator+(const Vector2& other) const
{
    return Add(other);
}

Vector2 Vector2::Multiply(const Vector2& other) const
{
    return Vector2(x * other.x, y * other.y);
}

Vector2 Vector2::operator*(const Vector2& other) const
{
    return Multiply(other);
}

int main()
{
    Vector2 position(4.0f, 4.0f);
    Vector2 speed(0.5f, 1.5f);
    Vector2 powerup(1.1f, 1.1f);

    Vector2 result = position.Add(speed.Multiply(powerup));
    Vector2 result2 = position + speed * powerup;

    std::cout << result2 << std::endl;

    std::cin.get();
}

问题:如果我想让它工作,我需要将我的 ostream& operator << 声明为好友。否则 MS Studio 会告诉我:“运算符的函数定义 << 未找到”!

我不明白为什么。我不需要将其他运算符声明为友元,那么在这种情况下为什么需要这样做?

谢谢。

operator<<必须定义为非成员函数(以及operator>>)。

让我们看一下当我们的 class 已经 operator<< 定义为成员函数 的情况下,我们将不得不像这样输出:

// Member function, lhs is bound to implicit this
ostream& operator<<(ostream&) const; 
Myclass obj;
obj << std::cout;

为什么会这样?因为您知道 重载运算符只是一个函数 。因此,对该函数的底层调用如下所示:

obj.operator<<(std::cout);

如果运算符是成员函数,就没办法了。由于我们无法修改库。

因此,为了让运算符访问私有数据成员,即 xy,我们必须将其声明为 friend.

算术运算符通常也应该是非成员函数,以允许对任一操作数进行转换。认为这不是必需的。这些也不应该改变它们操作数的状态并且应该产生一个新值,这也刺激从非成员函数接近它们。

此外,我建议您摆脱 using namespace std 并明确指定名称空间(或至少避免混淆)。

运算符 +* 被声明为 Vector2 的成员函数,因此它们自然能够访问 Vector2.

的私有成员

但是,您不能将规范的 IO 运算符(<<>>)声明为成员函数。行

friend ostream& operator << (ostream& stream, const Vector2& other);

不是成员函数的声明。它只是允许 free/non-member 函数 ostream& operator << (ostream& stream, const Vector2& other); 访问 Vector2.

的私有成员

没有这一行你应该得到错误

'Vector2::x': cannot access private member declared in class 'Vector2'

(或类似的东西)


但是,错误

"Function definition for operator << not found"

当您在实际代码中拆分声明和定义时可能会出现。如果你有这条线

friend ostream& operator << (ostream& stream, const Vector2& other);

Vector2 中您还声明了一个自由函数 ostream& operator << (ostream& stream, const Vector2& other); 并同时使它成为 Vector2 的友元。

如果删除此行,则不会在任何地方声明该函数。 (当然最后一部分只是猜测,但我得到的最好的猜测)