-2

I want to overload the operators + and = for my matrix class. My code is:

    friend float* operator+(const Matrix& m)
    {
        for(int i = 0; i < (int)(m._n*m._n); i++)
            _m[i] = _m[i] + m._m[i];
    };

    friend Matrix& operator=(const Matrix& m)
    {
        std::swap(_m, m._m);
        return *this;
    };

with _m the data and _n the size of the square matrices. But my compiler gives me the following errors:

main.cpp:161:45: error: ‘Matrix& operator=(const Matrix&)’ must be a nonstatic member function
main.cpp: In function ‘float* operator+(const Matrix&)’:
main.cpp:192:12: error: invalid use of non-static data member ‘Matrix::_m’
main.cpp:158:13: error: from this location
main.cpp:192:12: error: invalid use of non-static data member ‘Matrix::_m’
main.cpp:158:21: error: from this location
main.cpp:159:5: warning: no return statement in function returning non-void [-Wreturn-type]

For the first error, I have read that it has to be directly in the class, but even when I put it in there, I still get the error. For the second error, I have no idea how to solve this. What am I doing wrong?
Thank you!

arc_lupus
  • 3,942
  • 5
  • 45
  • 81
  • 5
    How does `float*` makes sense as a result of adding two matrices? – BartoszKP Jan 08 '14 at 14:19
  • If you put these functions in a class as members, then you can't have them declared as `friend`. That makes the functions non-member functions. – Some programmer dude Jan 08 '14 at 14:20
  • 1
    You can't swap from a `const` reference. You need to pass by value or make a local copy. – juanchopanza Jan 08 '14 at 14:21
  • Your `operator+` should be const. It should return a new matrix. It shouldn't modify `this` matrix. – leemes Jan 08 '14 at 14:24
  • @BartoszKP: My matrices consists of two arrays of length nxn, data type float. What would be a better return type for this function? – arc_lupus Jan 08 '14 at 14:24
  • 1
    How about `Matrix`? Adding two matrices should result in a matrix, not some internal representation the caller code shouldn't care about. – leemes Jan 08 '14 at 14:25
  • My matrix is created dynamically, so I can not create a new Matrix within this function and return it. – arc_lupus Jan 08 '14 at 14:26
  • Why? What's wrong with `Matrix result; result._m[...] = ...; return result;` ? – leemes Jan 08 '14 at 14:26
  • My matrix constructor needs a pointer to an existing memory space, which has to be allocated before. As far as I know, I can not allocate this in a function and return it because of memory leaks. Is this correct? – arc_lupus Jan 08 '14 at 14:28
  • That sounds like a bad design. Either manage memory in your class (constructor, copy constructor, copy assignment: allocation; destructor: deallocation) or implement it in terms of an existing data structure like `std::vector` which I **highly** recommend. – leemes Jan 08 '14 at 14:29
  • 2
    You should take the time to read what a [`friend` declaration](http://en.cppreference.com/w/cpp/language/friend) means. And as @leemes says your `operator+` should be `const` and returning a `Matrix`. Maybe you want to implement `operator+=`? If so, it should probably return `Matrix&`. – Praetorian Jan 08 '14 at 14:30
  • @leemes: I can not change the memory implementation, it is given by our lecturer... – arc_lupus Jan 08 '14 at 14:30
  • Please explain your lecturer that this is a bad design and ask him why he chose hit. So if you're bound to such a bad design, what you want is actually `operator+=`, that is, not returning a new, but modifying an existing Matrix. – leemes Jan 08 '14 at 14:32

2 Answers2

5

If you're defining something as friend in a class, it is not a member function, but a free-standing function can be defined (literally) inside of a class for convenience.

So operator=() should certainly not be friend but a simple member const Matrix& operator=(Matrix m) or const Matrix& operator=(const Matrix& m). By the way, you cannot use std::swap() if your parameter is const Matrix& m. You have to follow the copy-and-swap idiom.

For operator+() you should choose:

  • friend Matrix operator+(const Matrix& m1, const Matrix& m2)
  • Matrix operator+(const Matrix& m1) const.
Community
  • 1
  • 1
Johan
  • 3,728
  • 16
  • 25
1

I think you have misunderstood the friend concept a bit here:

Either use:

friend Matrix operator+(const Matrix& lhs,const Matrix& rhs);

Within the class and define the free function outside. (How you want to return a float* I do not know, so my implementation return a Matrix) Then you have to access your member variables like this:

{
    Matrix result; //insert correct constructor here.
    for(int i = 0; i < (int)(lhs._n*rhs._n); i++)
        result._m[i] = lhs._m[i] + rhs._m[i];
};

Or you go for an member operator+ like this

Matrix operator+(const Matrix& rhs) const;

Then you only have differ between access between this, rhs and your return value, and since you are returning a copy, you can keep it const correct.

Remember that friend functions does not have a thisand thus cannot access member variable directly.

For the assignment operator you cannot use a friend overload, this is because there already exist a default assignment operator provided by the compiler.

So here you have to provide within your class:

Matrix& operator=(const Matrix& a);
daramarak
  • 6,115
  • 1
  • 31
  • 50