Operator << überladen klappt nicht



  • Hallo,

    ich habe mir eine eigene Klasse Matrix4d geschrieben für 4-dimensionale Matrizen.

    Nun wollte ich für die Ausgabe den Operator "<<" überladen.

    Jedoch wird beim cout nur "0x804d048" ausgegeben, also scheinbar die Speicheradresse. Allerdings finde ich meinen Fehler nicht wirklich.

    Der Code dazu:

    Definition des Objekts:

    class Matrix4d{
    
    private:
    	double** a;
    
    public:
    
            double Matrix4d::getMatrix4d_value(unsigned int i, unsigned int j)
    
    ...
    };
    
    std::ostream& operator<< (std::ostream&, const Matrix4d&); //Ausgabe der Matrix
    

    Um die Werte der Matrix auszugeben:

    double Matrix4d::getMatrix4d_value(unsigned int i, unsigned int j) const {
    	if (i >= 4 || j >= 4) {
    		cerr << "Werte ausserhalb des Arrays!" << endl;
    		exit(0);
    	} else {
    		return this->a[i][j];
    	}
    }
    

    Ausgabe mit ostream:

    //Ausgabefunktion
    ostream& operator<< (ostream &os, const Matrix4d &Ausgabe) {
    	for (int i = 0; i < 4; i ++) {
    		os << endl;
    		for (int j = 0; j < 4; j++) {
    			os << Ausgabe.getMatrix4d_value(i, j) << ",";
    		}
    	}
    
    	return os;
    }
    

    Aufgerufen wird das ganze mit "cout << MATRIXNAME".

    Für Hilfe bin ich sehr dankbar.

    Gruß,

    Tobias



  • Es scheint so, als wird dein operator<< nicht gefunden. Ist er an der Stelle bekannt?



  • bin mir grade garnicht sicher, ob dein operator da nicht ziemlich falsch liegt.

    cout << MATRIXNAME ruft imo nicht den operator<< deiner Matrix auf, sondern den von cout.



  • Wie legst Du die Matrix denn an?



  • Jedoch wird beim cout nur "0x804d048" ausgegeben, also scheinbar die Speicheradresse.

    Das ist nicht nur scheinbar die Speicheradresse, das ist die Adresse deines Matrixobjektes.

    Pseudo:

    Matrix* myMatrix = new MyMatrix( ... );
    cout << myMatrix << endl;
    delete myMatrix;
    

    Hier wird die Adresse ausgegeben, da es sich um einen Pointer handelt. Entweder du definierst einen Stream-Operator für Matrix-Pointer (nicht sehr sinnvoll) oder du dereferenzierst den Pointer

    Pseudo:

    Matrix* myMatrix = new MyMatrix( ... );
    cout << *myMatrix << endl;
    delete myMatrix;
    

    oder verwendest direkt "normale" Objekte

    Pseudo:

    Matrix myMatrix( ... );
    cout << myMatrix << endl;
    

    Grüße... Heiko

    EDIT:

    double Matrix4d::getMatrix4d_value(unsigned int i, unsigned int j) const;
    

    Die Methode solltest du umbenennen. Den Klassennamen in der Methode zu wiederholen ist sinnfrei, da die Methode ohnehin an die Klasse gebunden ist. _value ist m.E. geschmacksache (was soll man sonst aus einer Matrix herausholen außer Werte?)

    double Matrix4d::get(size_t i, size_t j) const;
    


  • Hallo,

    vielen Dank schon mal für die schnellen Antworten.

    Die Matrix lege ich mit einem Copy-Konstruktor an, der Werte aus einem String ausliest und sie in double-Werte umwandelt:

    string matrixwerte = "(1,2,3,4)(5,6,7,8)(9,10,11,12)(13,14,15,16)";
     Matrix4d* matrixtest = new Matrix4d(matrixwerte);
    

    Die Klasse ist folgendermaßen in der Matrix4d.h definiert:

    class Matrix4d{
    
    private:
    	double** a;
    
    public:
    	Matrix4d();  //Default Konstruktor
    	Matrix4d(const string); //Copy-Konstruktor soll Double-Werte einlesen
    
    	bool operator== (const Matrix4d &) const; //Vergleich mit anderer Matrix
    	Matrix4d operator= (const Matrix4d &); //Kopieren der Matrix-Werte
    	Matrix4d operator+ (const Matrix4d &) const; //Addition zweier Matrizen
    	Matrix4d operator* (const Matrix4d &) const; //Matrizenmultiplikation
    	Matrix4d operator* (const double) const; //Matrix mit Skalar mult.
    	Vector3d operator* (const Vector3d &) const; //Mult mit Vektor
    	Matrix4d getMatrix4d() const; //get the Matrix
    	double getMatrix4d_value(unsigned int i, unsigned int j) const; 
    	void matrix4dwert(int i, int j, double value); //Wertzuweisung
    
    };
    
    std::ostream& operator<< (std::ostream&, const Matrix4d&); //Ausgabe der Matrix
    

    Die Matrix wird dann folgendermaßen angelegt:

    //Copy-Konstruktor
    Matrix4d::Matrix4d(const string Einlesen) {
    
    	this->a = new double*[4];
    
    	//Matrix erstellen
    	for (int i = 0; i < 4; i++) {
    		this->a[i] = new double[4];
    	}
    
    	//Matrix mit Nullen fuellen
    	for (int i = 0; i < 4; i++) {
    		for (int j = 0; j < 4; j++) {
    			this->a[i][j] = 0;
    		}
    	}
    
    	//Matrix mit lustigen Werten fuellen
    	int k = 0;
    	int l = 0;
    	string S = "";
    	for (unsigned int i = 1; i < Einlesen.length(); i++) {
    		if (Einlesen[i] != ',' && Einlesen[i] != '(' && Einlesen[i] != ')') {
    			S += Einlesen[i];
    		} 
    		else if (Einlesen[i] == ')') {
    			this->a[k][l] = atof(S.data());
    			k++;
    			S = "";
    			l = 0;
    		}
    		else if (Einlesen[i] == ',') {
    			this->a[k][l] = atof(S.data());
    			S = "";
    			l++;
    		} 
    	}
    }
    

    Und hier noch operator=, was wohl auch benutzt wird bei der "="-Zuweisung?

    //Kopieren der Matrix-Werte
    Matrix4d Matrix4d::operator= (const Matrix4d& mat2){ 
    
    	for(int i = 0; i < 4; i++){
    		for(int j = 0; j < 4; j++) {
    			this->a[i][j] = mat2.a[i][j];
    		}
    	}
    	Matrix4d test;
    
    	for(int i = 0; i < 4; i++){
    		for(int j = 0; j < 4; j++) {
    			test.a[i][j] = mat2.a[i][j];
    		}
    	}
    
    	return test;
    }
    

    Das mit dem Erstellen der Matrix klappt soweit auch.

    Wenn ich mit der Methode

    getMatrix4d_value(unsigned int i, unsigned int j)
    

    den Wert direkt ausgeben lasse, also

    matrixtest->getMatrix4d_value(...)
    

    kommt auch der Wert als Zahl zurück.

    Nur mit dem Operator << klappt es nicht, da kommt dieser Hex-Wert von oben...

    Gruß,

    Tobias



  • Hier wird die Adresse ausgegeben, da es sich um einen Pointer handelt. Entweder du definierst einen Stream-Operator für Matrix-Pointer (nicht sehr sinnvoll) oder du dereferenzierst den Pointer

    Pseudo:
    C/C++ Code:
    Matrix* myMatrix = new MyMatrix( ... );
    cout << myMatrix << endl;
    delete myMatrix;
    C/C++ Code:
    Matrix
    myMatrix = new MyMatrix( ... );
    cout << myMatrix << endl;
    delete myMatrix;
    C/C++ Code:
    Matrix
    myMatrix = new MyMatrix( ... );
    cout << *myMatrix << endl;
    delete myMatrix;

    Vielen Dank. Das war genau mein Fehler. Ich habe nicht daran gedacht, den Pointer zu dereferenzieren.

    Vielen Dank auch den anderen für die Hilfe.

    Gruß,

    Tobias


Anmelden zum Antworten