为什么覆盖运算符不能使用指针?
Why override operators aren't working with pointer?
我需要用覆盖运算符 + - * = 编写一个 class 矩阵,我有一些代码可以工作,但有错误。
//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;
}
覆盖运算符在此代码中工作正常
Matrix<int> matrix(2, 2);
matrix = matrix + matrix;
//and other operators work fine here
但是这里编译时报错
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix + matrix;
matrix = matrix * matrix;
//etc
错误
error C2804: binary "operator +" has too many parameters
类型信息在 C++ 中很重要。
这个:
Matrix<int> matrix(2, 2);
matrix = matrix + matrix;
这里matrix
的类型是Matrix
。您已经为类型 Matrix
定义了 operator +
,所以这工作正常。
第二个不同:
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix + matrix;
这里matrix
的类型是Matrix*
。注意 Matrix 末尾的星号(这使它成为 Matrix Pointer
)。这是与上面不同的类型。您尚未定义 operator +
对 Matrix*
的作用,因此编译器会查看其默认操作并找到一些接近但不够准确的内容,并生成一条试图提供帮助的适当错误消息。
要使用上面定义的 operator +
,您需要确保值的类型是 Matrix
和 NOT Matrix*
。您可以通过 operator *
.
取消引用指针,将 Matrix*
转换为 Matrix
Matrix<int>* matrix = new Matrix<int>(2, 2);
(*matrix) = (*matrix) + (*matrix);
此处:(*matrix)
取消引用 Matrix*
对象,您会得到一个 Matrix
。这现在可以正确地应用于您在上面定义的 operator +
。
但是说了这么多。
这解释了您的问题所在,但我认为您实际上不想(或不需要)在这种情况下使用 new
。
像这样动态分配内存可能不是实现它的正确方法。通常最好使用自动变量(因为这使内存管理更容易)。
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`
}
我需要用覆盖运算符 + - * = 编写一个 class 矩阵,我有一些代码可以工作,但有错误。
//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;
}
覆盖运算符在此代码中工作正常
Matrix<int> matrix(2, 2);
matrix = matrix + matrix;
//and other operators work fine here
但是这里编译时报错
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix + matrix;
matrix = matrix * matrix;
//etc
错误
error C2804: binary "operator +" has too many parameters
类型信息在 C++ 中很重要。
这个:
Matrix<int> matrix(2, 2);
matrix = matrix + matrix;
这里matrix
的类型是Matrix
。您已经为类型 Matrix
定义了 operator +
,所以这工作正常。
第二个不同:
Matrix<int>* matrix = new Matrix<int>(2, 2);
matrix = matrix + matrix;
这里matrix
的类型是Matrix*
。注意 Matrix 末尾的星号(这使它成为 Matrix Pointer
)。这是与上面不同的类型。您尚未定义 operator +
对 Matrix*
的作用,因此编译器会查看其默认操作并找到一些接近但不够准确的内容,并生成一条试图提供帮助的适当错误消息。
要使用上面定义的 operator +
,您需要确保值的类型是 Matrix
和 NOT Matrix*
。您可以通过 operator *
.
Matrix*
转换为 Matrix
Matrix<int>* matrix = new Matrix<int>(2, 2);
(*matrix) = (*matrix) + (*matrix);
此处:(*matrix)
取消引用 Matrix*
对象,您会得到一个 Matrix
。这现在可以正确地应用于您在上面定义的 operator +
。
但是说了这么多。
这解释了您的问题所在,但我认为您实际上不想(或不需要)在这种情况下使用 new
。
像这样动态分配内存可能不是实现它的正确方法。通常最好使用自动变量(因为这使内存管理更容易)。
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`
}