I need to write a class Matrix with override operators - * = and I've got some code that is works, but there is error.
//Matrix.h
template <class T>
class Matrix
{
public:
Matrix(int rows, int columns);
Matrix(const Matrix<T> &m);
Matrix<T>& operator=(Matrix<T>& m);
Matrix<T> operator (Matrix<T>& m) const;
Matrix<T>* operator*(Matrix<T>* m);
};
template <class T> Matrix<T>& Matrix<T>::operator*(Matrix<T>& m) {
Matrix<T>* newMatrix = new Matrix<T>(rowCount, m.colCount);
for (int i = 0; i < rowCount; i)
{
for (int j = 0; j < m.colCount; j)
{
newMatrix->data[i][j] = 0;
for (int k = 0; k < colCount; k)
newMatrix->data[i][j] = data[i][k] * m.data[k][j];
}
}
return *newMatrix;
}
And override operators work fine in this code
Matrix<int> matrix(2, 2);
matrix = matrix matrix;
//and other operators work fine here
But here it gives an error during compilation
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix matrix;
matrix = matrix * matrix;
//etc
error
error C2804: binary "operator " has too many parameters
CodePudding user response:
Type information is crutal in C .
This:
Matrix<int> matrix(2, 2);
matrix = matrix matrix;
Here the type of matrix
is Matrix
. You have defined what the operator
for the type Matrix
so this works fine.
This second one is different:
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix matrix;
Here the type of matrix
is Matrix*
. Notice the star on the end of Matrix (this makes it a Matrix Pointer
). This is a different type than above. You have not defined what operator
does for Matrix*
so the compiler looks at its default operations and finds something close but not exact enough and generates an appropriate error message that tries to help.
To use the operator
you defined above you need to make sure the types of the values are Matrix
and NOT Matrix*
. You can covert a Matrix*
into a Matrix
by dereferencing the pointer via operator *
.
Matrix<int>* matrix = new Matrix<int>(2, 2);
(*matrix) = (*matrix) (*matrix);
Here: (*matrix)
dereferences the Matrix*
object and you get a Matrix
. This can now correctly be applied to the operator
you defined above.
But saying all that.
That explains whay your problem is, but I don't think you actually want (or need) to use new
in this context.
Dynamically allocating memory like this is probably not the correct way to implement this. It is usually better to use automatic variables (as this makes memory management easier).
template <class T>
Matrix<T> Matrix<T>::operator*(Matrix<T>& m)
// I also removed the & from the return value
// So that the value is copied out of the function.
// because with dynamic allocation the result will disappear
// after the function exits.
// Note: Though the matrix may be officially copied out
// the compiler is likely to optimize away this copy.
// and when you upgrade your class with move semantics
// then it will definitely be moved.
{
Matrix<T> newMatrix(rowCount, m.colCount);
// Remove the Pointer from the above line.
// And fix the -> into . in the code below.
for (int i = 0; i < rowCount; i)
{
for (int j = 0; j < m.colCount; j)
{
newMatrix.data[i][j] = 0;
for (int k = 0; k < colCount; k)
newMatrix.data[i][j] = data[i][k] * m.data[k][j];
}
}
return newMatrix;
// Now you can remove the * from the return value.
// The code works exactly the same.
// But you have not leaked the memory you allocated with `new`
}