Home > Mobile >  Why override operators aren't working with pointer?
Why override operators aren't working with pointer?

Time:12-21

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`
}
  • Related