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



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

Matrix m1, m2, m3;
...
m3 = m1 * m2;

以及等表达

Vector v1, v2;
Matrix m;
...
v2 = m * v1;


第一个重载似乎很容易,因为它只是Matrix类的一个成员函数:

class Matrix {
    public:
        Matrix operator*(Matrix &m)
}

摘录自CCD_ 4。

但是,我不确定在哪里/如何声明/定义运算符的其他重载。我曾认为我需要一个friend函数来访问这两个类的私有成员,所以我在Vector类中尝试了以下声明:

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

摘录自CCD_ 7。

这似乎遵循了我在接受的答案中发现的这个问题的模式,尽管这是另一个运算符的过载。然而,当我试图编译定义重载的源文件时,我会遇到错误,因为它无法访问Matrix类的私有成员。

我看到的大多数其他问题和答案都试图重载一个二进制运算符来处理同一类的两个实例,就像我的第一个例子一样,事实上,我的链接答案是我唯一看到类似于我正在做的事情的地方。

那么应该如何定义呢?

编辑:

对于可能的重复,公认的答案是"仅当它需要访问私有成员时才将其设为friend"。我确实需要访问私有会员,但我的编译器告诉我,即使将其设成friend,我仍然无法访问Matrix的私有会员。

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

只需将它们作为常规函数在任何类之外实现即可。

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

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

首先,您重载了错误的运算符。两个参数运算符应始终作为自由函数重载,而不是作为类成员重载,并且默认为*=运算符。不要让他们成为朋友,只是把他们当作常规活动。

最新更新