C++运算符+和运算符+=重载

发布于 2024-10-06 16:39:33 字数 1730 浏览 3 评论 0原文

我正在用 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);
        }
    }

}

I'm implementing my own matrix class in c++ to help me develop my understanding of the language. I read somewhere that if you've got a working += operator, to use it in your + operator. So that's what I've got:

template <class T>
const Matrix<T>& Matrix<T>::operator+(const Matrix<T> &R){

    Matrix<T> copy(*this);
    return copy += R;
}

And here is the += operator overload:

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

I can use the += just fine (eg, a += b; returns no errors). But calling the + operator (eg, a = b + c;) returns :

test.cpp.out(77055) malloc: *** error for object 0x300000004: pointer being freed was not allocated

Just for completeness, here's my destructor:

template <class T>
Matrix<T>::~Matrix(){
    for (int i = 1; i < rows; i++){
        delete[] data[i]; }
    delete[] data;
}

I've been using C++ for a couple years on and off, and still have trouble sometimes keeping track of pointers. I hope that's normal...
Any help would be great. Thanks!

EDIT: here's my copy constructor. It was set to free the data arrays but i removed that. now I get segmentation faults.

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

≈。彩虹 2024-10-13 16:39:33

operator+() 不应返回引用类型,因为它是保存操作结果的新(本地声明)实例。

operator+() should not return a reference type as it is a new (locally declared) instance that holds the result of the operation.

淡莣 2024-10-13 16:39:33

这就是我为矩阵类实现此类运算符的方式,它基于向量类。一旦定义了一些运算符,所有其他运算符都应该根据最简单的运算符来定义:

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

This is how I have implemented such operators for a Matrix class, this is based on a Vector Class. Once you define some operators all other should be defined in terms of the simplest operators:

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;
}
会傲 2024-10-13 16:39:33

如果这是一个用于 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 对象。

If this a matrix for 3D rendering/simulation I would recommend NOT dynamically allocating the memory like that. You can end up with the memory being spread all over the place which causes caching issues. It also leads to potential memory bugs.

template <typename T>
class Matrix
{
   public:
      T   m_Data[4][4];
};

or if you want something non-4x4

template <typename T, unsigned int rows, unsigned int columns>
class Matrix
{
   public:
      T   m_Data[rows][columns];
};

and then dynamically allocate the Matrix objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文