我正在用c ++实现我自己的矩阵类,以帮助我提高对语言的理解。我读到某个地方,如果你有一个工作+ =运算符,在你的+运算符中使用它。这就是我所拥有的:
template <class T>
const Matrix<T>& Matrix<T>::operator+(const Matrix<T> &R){
Matrix<T> copy(*this);
return copy += R;
}
这是+ =运算符重载:
template <class T>
const Matrix<T>& Matrix<T>::operator+=(const Matrix<T> & second_matrix){
//Learn how to throw errors....
if (rows != second_matrix.getNumRows() || cols != second_matrix.getNumCols()){throw "Dimension mismatch.";}
int i,j;
for (i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
data[i][j] += second_matrix.get(i,j);
}
}
return *this;
}
我可以使用+ =就好了(例如,a + = b;不返回任何错误)。但是调用+运算符(例如,a = b + c;)会返回:
test.cpp.out(77055) malloc: *** error for object 0x300000004: pointer being freed was not allocated
为了完整起见,这是我的析构函数:
template <class T>
Matrix<T>::~Matrix(){
for (int i = 1; i < rows; i++){
delete[] data[i]; }
delete[] data;
}
我一直在使用C ++几年,并且有时候仍然有问题跟踪指针。我希望这是正常的...... 任何帮助都会很棒。谢谢!
编辑:这是我的复制构造函数。它被设置为释放数据阵列,但我删除了它。现在我得到了分段错误。
template <class T>
Matrix<T>::Matrix(const Matrix<T>& second_matrix){
rows = second_matrix.getNumRows();
cols = second_matrix.getNumCols();
data = new T*[rows];
int i,j;
for (i = 0; i < rows; i++){
data[i] = new T[cols];
}
for (i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
data[i][j] = second_matrix.get(i,j);
}
}
}
答案 0 :(得分:22)
operator+()
不应该返回引用类型,因为它是一个保存操作结果的新(本地声明的)实例。
答案 1 :(得分:2)
如果这是一个用于3D渲染/模拟的矩阵,我建议不要像这样动态分配内存。你最终可能会将内存传播到整个地方,从而导致缓存问题。它还会导致潜在的内存错误。
template <typename T>
class Matrix
{
public:
T m_Data[4][4];
};
或者如果你想要非4x4的东西
template <typename T, unsigned int rows, unsigned int columns>
class Matrix
{
public:
T m_Data[rows][columns];
};
然后动态分配Matrix对象。
答案 2 :(得分:2)
这就是我为 Matrix类实现此类运算符的方法,它基于向量类。一旦定义了一些运算符,所有其他运算符都应该根据最简单的运算符来定义:
Matrix::Matrix(const Matrix& rMatrix) :
_iRows(rMatrix._iRows), _iColumns(rMatrix._iColumns), _pVector(0)
{
_pVector = new Vector[_iRows];
for (int i = 0; i < _iRows; i++) { _pVector[i] = rMatrix._pVector[i]; }
}
Matrix& Matrix::operator=(const Matrix& rMatrix)
{
if (this != &rMatrix)
{
if (0 != _pVector) { delete[] _pVector; pVector = 0; }
_iRows = rMatrix._iRows;
_iColumns = rMatrix._iColumns;
_pVector = new Vector[_iRows];
for (int i = 0; i < _iRows; i++) { _pVector[i] = rMatrix._pVector[i]; }
}
return *this;
}
Matrix& Matrix::operator+=(const Matrix& rMatrix)
{
*this = *this + rMatrix;
return *this;
}
Matrix Matrix::operator+(const Matrix& rMatrix) const
{
Matrix matrix(_iRows, _iColumns);
ValidateSizes(rMatrix);
for (int i = 0; i < _iRows; i++) { matrix._pVector[i] = _pVector[i] + rMatrix._pVector[i]; }
return matrix;
}
Matrix operator+(const Matrix& rMatrix, double dNum)
{
Matrix matrix(rMatrix._iRows, rMatrix._iColumns);
matrix.ValidateSizes(rMatrix);
for (int i = 0; i < matrix._iRows; i++) { matrix._pVector[i] = dNum + rMatrix._pVector[i]; }
return matrix;
}
Matrix operator+(double dNum, const Matrix& rMatrix)
{
return operator+(rMatrix, dNum);
}
bool Matrix::ValidateSizes(const Matrix& rMatrix) const
{
if (_iRows != rMatrix._iRows) { /* THROW EXCEPTION */ }
if (_iColumns != rMatrix._iColumns) { /* THROW EXCEPTION */ }
return true;
}