2010-12-07 31 views
5

言語の理解を深めるために、C++で独自の行列クラスを実装しています。 + +演算子を使用している場合は、+演算子で使用することをお勧めします。C++演算子+演算子+ =オーバーロード

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、例えば(+ =罰金を使用することができ、エラーを返しません:

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

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

そしてここでは、+ =演算子のオーバーロードです:だから、それは私が持っているものです)。しかし、+演算子を呼び出す(例えば、A = B + Cは;)を返します:私は数年のためのC++を使用してきた

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

ただ完全を期すために、ここに私のデストラクタです
test.cpp.out(77055) malloc: *** error for object 0x300000004: pointer being freed was not allocated 

そして時にはポインタを追跡している時にも問題があります。私はそれが正常であることを願っています... 助けが素晴らしいでしょう。ありがとう!

編集:私のコピーコンストラクタです。データ配列を解放するように設定されていましたが、削除しました。今私はセグメンテーションフォールトを得る。それは操作の結果を保持している新しい(ローカルに宣言された)インスタンスであるよう

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

} 
+3

コピーコンストラクタの外観は?エラーがメモリが2回解放されていることを示しているので、おそらくあなたの問題です。 –

+0

@ Walt W:これはBig Threeの問題だと思う。 –

+1

@Fred:大きな3つの問題は何ですか? – jakev

答えて

18

operator+()は、参照型を返すべきではありません。

+4

+1:すぐにオブジェクト(Matrixコピー)への参照を返しますスタックがアンロードされると破壊されます。 C++の参照はJava/C#/ etcの参照と同じではありません。 –

1

これを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]; 
}; 

何かをしたい、その後、動的マトリックスオブジェクトを割り当てる場合。

+0

これは話題にはなりませんが、私はいくつかの3D作業を行いました。そこに私の行列クラスを使いたいと思っています。任意のリンクや他のアドバイス? – jakev

1

これは、マトリックスクラスのためにこのような演算子を実装した方法です。ベクトルクラスに基づいています。いったんいくつかの演算子を定義すると、他のすべての演算子は最も単純な演算子で定義する必要があります。

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; 
} 
関連する問題