我应该如何正确重载使用 friend 的运算符?

How should I overload operators using friend correctly?

我有一个Matrix class和一个Vector class,它们在头文件中有声明,在它们自己的源文件中有定义,我想重载* 运算符有两种方式。我希望能够写出像

这样的表达式
Matrix m1, m2, m3;
...
m3 = m1 * m2;

还有像

这样的表达
Vector v1, v2;
Matrix m;
...
v2 = m * v1;


第一次重载看起来很简单,因为它只是 Matrix class:

的一个成员函数
class Matrix {
    public:
        Matrix operator*(Matrix &m)
}

摘自 matrix.hpp

但是,我不确定 where/how 到 declare/define 运算符的其他重载。我以为我需要一个 friend 函数来访问两个 classes 的私有成员,所以我在 Vector class 中尝试了以下声明:

class Vector {
    public:
        friend Vector operator*(const Matrix &m, const Vector &v);
}

摘自 vector.hpp

这似乎遵循了我在接受的答案中 this question 中发现的模式,尽管它重载了不同的运算符。但是,当我尝试编译定义重载的源文件时,出现错误,因为它无法访问 Matrix class 的私有成员。

我看到的大多数其他问题和答案都试图重载二元运算符以作用于相同 class 的两个实例,就像我的第一个例子,事实上我的链接答案是 THE只有在我看到与我正在做的事情类似的地方。

那么这个应该怎么定义呢?

编辑:

已接受的 the possible duplicate 答案指出 "Make it friend ONLY when it needs to access private members." 我确实需要访问私有成员,但我的编译器告诉我即使在访问之后 friend 我仍然无法访问Matrix.

的私有成员

他们不需要被定义为会员或朋友,除非VectorMatrix classes是完全不透明的(这对每个使用它们的人来说都是不方便的) .

只需将它们作为常规函数实现,在任何 class.

之外
Vector operator*(const Matrix &a, const Vector &b);
Vector operator*(const Vector &a, const Matrix &b);

我建议不要使矢量和矩阵组件不可访问。要么公开成员变量,要么提供一个operator[],可用于实现上述功能。

首先,您重载了错误的运算符。双参数运算符应始终作为自由函数重载,而不是 class 成员 - 而不是默认为 *= 运算符。并且不要让他们成为朋友,只是让他们成为常规功能。