1

I have a Matrix class and a Vector class, which have declarations in header files and definitions in their own source files, and I want to overload the * operator two ways. I would like to be able to write expressions like

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

and also expressions like

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


The first overloading seems easy, as it's simply a member function of the Matrix class:
class Matrix {
    public:
        Matrix operator*(Matrix &m)
}

excerpt from matrix.hpp.

However, I am not sure where/how to declare/define the other overloading of the operator. I had thought that I needed a friend function to be able to access the private members of both classes, so I tried the following declaration in the Vector class:

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

excerpt from vector.hpp.

This seemed to follow the pattern I found in this question in the accepted answer, although it is overloading of a different operator. However, when I try to compile my source files that define the overloading, I get errors because it can't access the private members of the Matrix class.

Most of the other questions and answers I've seen are attempting to overload a binary operator to act on two instances of the same class, like my first example, and in fact my linked answer is THE ONLY place I've seen something similar to what I'm doing.

So how should this be defined?

EDIT:

The accepted answer to the possible duplicate states "Make it friend ONLY when it needs to access private members." I do need to access private members, but my compiler tells me that even after making it friend I still can't access the private members of Matrix.

Community
  • 1
  • 1
rjmcf
  • 103
  • 3
  • 12

2 Answers2

4

They don't need to be defined as member or friends, unless the Vector and Matrix classes are completely opaque (that would be inconvenient for everyone using them).

Just implement them both as regular functions, outside any class.

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

I would recommend against making the vector and matrix components inaccessible. Either expose the member variables or provide an operator[] which can be used for implementing the above functions.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • I didn't want to give users access to each individual element of a matrix or vector, so I made each element private and didn't provide accessors. Would there be a way to do it with those constraints? – rjmcf Dec 24 '15 at 20:30
  • 1
    @rjmcf: The whole point of making a member private is to prevent people from accidentally misusing your class, and shielding users from changes in implementation details. However, in this case, it is a mistake. There is a saying, "If all you have is a hammer, then everything looks like a nail." In this case, the "hammer" is your ability to make classes opaque, *even when it is a bad idea.* – Dietrich Epp Dec 24 '15 at 20:34
  • Ok, I'll concede. Thanks for the advice! – rjmcf Dec 24 '15 at 20:37
  • It might be worth noting that overloading `operator()` was actually what was best, given that matrices need more than one subscript. – rjmcf Dec 24 '15 at 21:09
-1

First of all, you are overloading wrong operators. Two-argument operators should always be overloaded as a free-function, not a class member - and than default to *= operator. And do not make them friends, just have them as regular functions.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • For my second example, that means executing `m1*=v1` and that returning a vector. Is that acceptable? – rjmcf Dec 24 '15 at 20:31