2014-09-15 2 views
1

Как создать оператор, который будет выполнять умножение без изменения исходных значений?Оператор умножения меняет исходные значения

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

    return *this; 
} 

Итак ...

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 

Такое поведение полностью ожидается, и делает абсолютный смысл, но как я могу избежать этого происходит?

Я хочу mulitply m1 от m2 и оставляйте их неизменными, но обновление mNew. Я думаю, что мне нужен метод с 2 параметрами, входящими (аналогично оператору в этом потоке -> [simple c++: How to overload the multiplication operator so that float*myClass and myClass*float works), но я не могу найти приемлемое определение, которое разрешит мой компилятор.

+3

Ваша перегрузка требует создания отдельного экземпляра и возврата по значению. –

+0

@bkausbk: Нет, это все равно изменит матрицу, прежде чем вернуть ее копию. Вам нужно создать новую матрицу для хранения результата. –

ответ

3

Ваша реализация operator* должна быть функцией-членом в operator*=, который изменит именующее выражение; и добавить функцию, не являющихся членами operator*, которая не изменит исходное значение:

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

Обратите внимание, что здесь operator* является нечлена функция, так что она будет иметь желаемое свойство принимать то же самое неявные преобразования по его левой стороне и правым параметрам. И всегда предпочитайте делать функции nonmember nonfriends для улучшения инкапсуляции путем минимизации зависимостей.

+0

Я пробовал это, но он говорит: «Ошибка C2804: двоичный оператор» имеет слишком много параметров » – Beakie

+0

@Beakie Оператор' * 'должен быть нечленом (или членом' Matrix3 operator * (const Matrix3 & rhs) const; ' – juanchopanza

+0

Итак, у меня не было его как метода, не являющегося членом. – Beakie

1

Я расширить комментарий Оливер:

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

    //do multiplication 

    return copy; 
} 
+0

Это отлично работает. Хороший! – Beakie

1

Операция, которую вы пытаетесь сделать делает, имеет смысл, однако вы не должны возвращаться по ссылке, чтобы выполнить ее, что не имеет смысла. Проблема с возвратом по ссылке - оператор * создает новый объект.

Я предлагаю изменить свой код, чтобы что-то вроде этого:

//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; 
} 

В принципе, вы создаете переменный экземпляр, заселение его с содержимым вашего объекта, провести умножение, вернуть переменный экземпляр.