2010-12-07 10 views
5

저는 언어에 대한 이해를 돕기 위해 C++에서 고유 한 행렬 클래스를 구현하고 있습니다. 어딘가에 + + 연산자가 있으면 + 연산자에서 사용할 수 있다고 읽었습니다.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; 
} 

내가 + = 예를 들면, + = B (잘 사용할 수 있습니다 반환하지 오류를). 그러나 + 연산자를 호출 (예를 들면, A = B + C를) 반환 I가 몇 년 동안 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

복사 생성자는 어떤 모양입니까? 그 오류는 메모리가 두 번 해제되었음을 나타 내기 때문에 문제 일 가능성이 높습니다. –

+0

@Walt W : 네, 이것이 Big Three 문제라고 생각합니다. –

+1

@Fred : 큰 세 가지 문제가 무엇인가요? – jakev

답변

18

operator+()는 참조 타입을 리턴 안된다.

+4

+1 : 즉시 참조 인 객체 (매트릭스 사본)에 대한 참조를 반환합니다. 스택이 언로드 될 때 파괴된다. C++ 참조는 Java/C#/etc 참조와 동일하지 않습니다. –

1

3D 렌더링/시뮬레이션을위한 매트릭스 인 경우 동적으로 메모리를 할당하지 않는 것이 좋습니다. 캐시 문제를 야기하는 곳곳에 메모리가 확산 될 수 있습니다. 또한 잠재적 인 메모리 버그가 발생합니다.

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

하거나

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

일이 아닌 4 × 4

을 원하고 동적으로 매트릭스 객체를 할당합니다.

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