timestamp
Mitglied Käsekuchen
Hallo Forum,
ich versuche mich derzeit an einer Matrizenklasse und habe dazu mehrere Fragen:
Zunächst der Code:
Meine Fragen dazu:
1) Ist der Dekonstruktor überhaupt notwendig?
2) Ich möchte auf jeden Fall Chaining von Operatoren erlauben. Dazu muss ich ja eine Referenz (Matrix&) zurückgeben, oder? Scheinbar klappt das aber nicht so ganz, denn die Matrizen die ich erhalte sind ja alle 0. Wenn ich keine Referenz zurückgebe (ich brauche sogar nicht mal ein return) dann klappt die Addition. Chaining schlägt allerdings fehl.
3) Schreibe ich cout<<A+B; dann schlägt die Assertion (i>=0 && i <= _m) fehl und mein Programm stürzt ab. Das verstehe ich auch nicht.
ich versuche mich derzeit an einer Matrizenklasse und habe dazu mehrere Fragen:
Zunächst der Code:
C++:
#ifndef MATRIX_H
#define MATRIX_H
#include <ostream>
class Matrix{
public:
/** Default constructor */
Matrix(int m, int n);
Matrix(const Matrix& A);
~Matrix();
Matrix& operator+=(Matrix& A);
Matrix& operator-=(Matrix& A);
Matrix& operator*=(Matrix& A);
Matrix& operator*=(double d);
Matrix& operator/=(double d);
Matrix& operator=(Matrix& A);
double& operator()(int i, int j) const;
friend std::ostream& operator<<(std::ostream& out, Matrix& A);
friend Matrix& operator+( Matrix& A, Matrix& B);
friend Matrix& operator-( Matrix& A, Matrix& B);
friend Matrix& operator*( Matrix& A, Matrix& B);
friend Matrix& operator*( Matrix& A, double d);
friend Matrix& operator*(double d, Matrix& A);
friend Matrix& operator/( Matrix& A, double d);
Matrix transpose();
Matrix inverse();
inline int n(){ return _n; };
inline int m(){ return _m; };
//Matrix gauss(Vector& v);
protected:
private:
double** _matrix;
int _m, _n;
};
#endif // MATRIX_H
C++:
//Matrix.cpp
#include "Matrix.h"
#include <cassert>
#include <ostream>
#include <iostream>
Matrix::Matrix(int m, int n) : _m(m), _n(n){
_matrix = new double*[_m];
for( int i = 0; i < _m; i++ ){
_matrix[i] = new double[_n] {};
}
}
Matrix::Matrix(const Matrix& A){
_m = A._m;
_n = A._n;
_matrix = new double*[_m];
for( int i = 0; i < _m; i++ ){
_matrix[i] = new double[_n] {};
for( int j = 0; j < _n; j++ ){
(*this)(i, j) = A(i, j);
}
}
}
Matrix::~Matrix(){
delete _matrix;
}
Matrix& Matrix::operator+=(Matrix& A){
assert(_m == A._m && _n == A._n);
for( int i = 0; i < A._m; i++ ){
for( int j = 0; j < A._n; j++ ){
(*this)(i, j) += A(i,j);
}
}
return *this;
}
Matrix& Matrix::operator-=(Matrix& A){
assert(_m == A._m && _n == A._n);
for( int i = 0; i < A._m; i++ ){
for( int j = 0; j < A._n; j++ ){
(*this)(i, j) -= A(i,j);
}
}
return *this;
}
Matrix& Matrix::operator=(Matrix& A){
delete _matrix;
_m = A._m;
_n = A._n;
_matrix = new double*[_m];
for( int i = 0; i < _m; i++ ){
_matrix[i] = new double[_n];
for( int j = 0; j < _n; j++ ){
_matrix[i][j] = A(i, j);
}
}
return *this;
}
Matrix& operator+(Matrix& A, Matrix& B){
assert( A._m == B._m && A._n == B._n );
Matrix C(A);
for( int i = 0; i < A._m; i++ ){
for( int j = 0; j < A._n; j++ ){
C(i,j) += B(i,j);
}
}
return C;
}
Matrix& operator-(Matrix& A, Matrix& B){
assert( A._m == B._m && A._n == B._n );
Matrix C(A);
for( int i = 0; i < A._m; i++ ){
for( int j = 0; j < A._n; j++ ){
C(i,j) = A(i,j)-B(i,j);
}
}
return C;
}
Matrix& Matrix::operator*=(double d){
for( int i = 0; i < _m; i++ ){
for( int j = 0; j < _n; j++ ){
(*this)(i, j) *= d;
}
}
return *this;
}
Matrix& operator*(Matrix& A, double d){
Matrix B(A);
for( int i = 0; i < A._m; i++ ){
for( int j = 0; j < A._n; j++ ){
B(i, j) *= d;
}
}
return B;
}
double& Matrix::operator()(int i, int j) const{
assert(i >= 0 && i < _m);
assert(j >= 0 && j < _n);
return _matrix[i][j];
}
std::ostream& operator<<(std::ostream& out, Matrix& A){
for( int i = 0; i < A._m; i++ ){
out << "( ";
for( int j = 0; j < A._n; j++ ){
if( j > 0 ){
out << "\t";
}
out << A(i, j);
}
out << ")" << std::endl;
}
return out;
}
C++:
//main.cpp
#include <iostream>
#include <typeinfo>
#include "Matrix.h"
#include "MathLib.h"
using namespace std;
int main(){
Matrix A(2, 2);
Matrix B(2, 2);
A(0, 0) = 1;
A(0, 1) = 0;
A(1, 0) = 0;
A(1, 1) = -1;
B(0, 0) = 1;
B(0, 1) = 2;
B(1, 0) = 3;
B(1, 1) = 4;
A = B;
cout << A; // Liefert B
Matrix C = A+B;
cout << C; // Gibt Null Matrix
Matrix D(C);
cout << D; // Gibt Null Matrix
Matrix E(A+B+C);
cout << E; // Gibt Null Matrix
return 0;
}
Meine Fragen dazu:
1) Ist der Dekonstruktor überhaupt notwendig?
2) Ich möchte auf jeden Fall Chaining von Operatoren erlauben. Dazu muss ich ja eine Referenz (Matrix&) zurückgeben, oder? Scheinbar klappt das aber nicht so ganz, denn die Matrizen die ich erhalte sind ja alle 0. Wenn ich keine Referenz zurückgebe (ich brauche sogar nicht mal ein return) dann klappt die Addition. Chaining schlägt allerdings fehl.
3) Schreibe ich cout<<A+B; dann schlägt die Assertion (i>=0 && i <= _m) fehl und mein Programm stürzt ab. Das verstehe ich auch nicht.