Beakie
Beakie

Reputation: 2009

Multiplication operator is changing original values

How can I create an operator that will perform multiplication without changing the original values?

Matrix3 & operator*(const Matrix3 &matrix)
{
     //do multiplication

     return *this;
}

So...

Matrix3 m1 = Matrix3(1, 2, 3, 3, 2, 1, 2, 1, 3);
Matrix3 m2 = Matrix3(4, 5, 6, 6, 5, 4, 4, 6, 5);

Matrix3 mNew = m1 * m2; <--- mNew is now correct, but it has also changed m1

This behavior is totally expected and makes absolute sense, but how can I avoid it happening?

I want to mulitply m1 by m2 and leave them unchanged, only updating mNew. I think I want a method with 2 params coming in (similar to the operator in this thread -> [simple c++: How to overload the multiplication operator so that float*myClass and myClass*float works) but I can't find an acceptable definition that my compiler will allow.

Upvotes: 1

Views: 168

Answers (3)

songyuanyao
songyuanyao

Reputation: 172994

Your implementation of operator* should be a member function as operator*=, which will change the lvalue; and add a non-member function operator*, which will not change the original value:

class Matrix3 {
public:
    Matrix3 & operator*=(const Matrix3 &matrix)
    {
        //do multiplication

        return *this;
    }    
};

Matrix3 operator*(const Matrix3 &matrix1, const Matrix3 &matrix2)
{
    Matrix3 m( matrix1 );
    return m *= matrix2;
}

DEMO

Note that here operator* is a nonmember function, so that it will have the desirable property of accepting the same implicit conversions on its left-hand side and right-hand side parameters. And always prefer making functions nonmember nonfriends to improve encapsulation by minimizing dependencies.

Upvotes: 3

Luke Dupin
Luke Dupin

Reputation: 2305

The operation you are trying to do does make sense, however you shouldn't return by reference to accomplish it, that doesn't make sense. The issue with returning by reference is the * operator is creating a new object.

I suggest changing your code to something like this:

//Notice no return by reference here
Matrix3 operator*(const Matrix3 &matrix)
{
 //Copy my local object into a temp instance variable
 Matrix3 m = *this;
 return m *= matrix;
}

//Notice return by reference here
Matrix3& operator*=(const Matrix3 &matrix)
{
 //Multiple matrix to *this
 return *this;
}

Basically, you're creating an instance variable, populating it with the contents of your object, conduct the multiplication, return your instance variable.

Upvotes: 1

Nim
Nim

Reputation: 33645

I'll expand Oliver's comment:

Matrix3 operator*(const Matrix3 &matrix) const
{
     Matrix3 copy(*this);

     //do multiplication

     return copy;
}

Upvotes: 1

Related Questions