... einmal mehr: class Matrix



  • hEY gUYS!
    mal wieder geht es um die Implementation einer eigenen Klasse für 2.dimensionale Matrizen.
    1st: Ich überlade gerade alle möglichen Operatoren, aber bei dem Indexoperator, den ich als getter (und setter - ja, ja ich weiß, beides wird etwas kompliziert, deshalb erstmal nur getter) für die Elemente in der Matrix benutzen will, habe ich Probleme: ich habe ihn als Methode Matrix::operator() implementiert (s.u.). Funktioniert wunderbar, aber warum kann ich ihn nicht als freie Funktion definieren und innerhalb mit den einfachen gettern arbeiten??
    Aber ich hätte gerne einen Indexoperator der Form operator[][], so daß ich als getter ganz normal die []-Klammern benutzen kann. *KnotenImGehirn*
    2nd: die einfachen getter habe ich inline definiert, z.B.:

    inline unsigned int get_numRows(void)const;
    

    Ist es wirklich so, daß der Zugriff auf die Attribute damit genau so schnell wie der direkte Zugriff ist, also kein Overhead entsteht? (sonst wäre die Implementation des operator+ als freie Funktion suboptimal)
    3rd: operator+ und operator<< als freie Funktionen und nicht als friend: eure Meinung
    Die Frage wurde schon mal in (s. link) behandelt, aber der "Schlußsatz" fehlt.
    http://www.c-plusplus.net/forum/viewtopic.php?t=75611&postdays=0&postorder=asc&start=10

    und hier noch ein bißchen source:

    //.h
    #ifndef _MATRIX_H_
    #define _MATRIX_H_
    
    class Matrix{
    
    	private:
    
    		//Attribute (Eigenschaften)
    		unsigned int numRows;
    		unsigned int numCols;
    		double ** elem;
    
    	public:  ...........
                    ...................				
    //.cpp
    
    //caution: operator() only usable as getter-method!
    double Matrix::operator()(unsigned int row, unsigned int col)const{
    
    	return ( elem[row][col] );
    }
    //----------------------------------------------------------------------------------
    //freie Funktionen
    //----------------------------------------------------------------------------------
    const Matrix operator+(const Matrix & mat01, const Matrix & mat02){
    
    	Matrix matSum(mat01);
    
    	matSum += mat02;
    
    	return matSum;
    } 
    //----------------------------------------------------------------------------------
    ostream & operator<<(ostream & os, const Matrix & matrix){
    
    	os << "Matrix (" << matrix.get_numRows() 
    	   << " X "      << matrix.get_numCols() 
    	   << "):" << endl;
    
    	for(int row=0; row<matrix.get_numRows() ;row++){
    		for(int col=0; col<matrix.get_numCols() ;col++){
    
    			os << matrix.get_elem(row,col) << " ";
    		}
    		os << endl;
    	}
    
    	return os;
    }
    

    post scriptum:
    freshman.greets(Lu); // 😃 😉



  • class matrix
    {
    private:
        std::size_t rowc;
        std::size_t colc;
        double** v;
    public:
        double* operator[](std::size_t index)
        {
            assert(index<rowc);
            return v[index];
        };
        const double* operator[](std::size_t index)const
        {
            assert(index<rowc);
            return v[index];
        };
    };
    

    Evtl. willst du den Vektor auch autom. vergrößern oder so...
    /edit: ja, inline macht keinen Performanceverlust.
    du kannst auch methoden außerhalb der Klasse inlinen.
    wenn du den öffentl. operator [] benutz, brauchst du kein friend...



  • thx' ich mache mich jetzt mal zuerst über assert() schlau, kenn eich nämlich nicht.
    aber: warum std::size_t und nicht explizit <unsigned int> (ja, ich weiß, daß size_t als unsigned int definiert ist) ?
    du würdest also auch die 'freie' Variante bevorzugen und nicht friend, oder? argumente dafür?

    andere Frage:
    Fehlerhandling: sollte ich für jeden möglichen Fehler eine eigene Exception-Klasse schreiben?



  • Wenn NDEBUG nicht definiert ist, beendet assert das Programm (und wenns ne schlaue implementierung ist, gibts sogar ne Fehlermeldung aus). Sobald du NDEBUG definierst, entfernt der preprozessor alle asserts aus dem Quellcode.
    Prinzipiell ist es mir egal, ob ich friend benutze oder nicht, aber was ohne geht, mach ich ohne, ist übersichtlicher so, finde ich...
    /edit: size_t: da gabs schon viele diskussionen, guck z.B. mal kingruedis sig. Ich benutze es nicht immer, meistens mach ich nen neuen templateparameter dafür auf...



  • @ness: dein operator[] ist echt schick! gefällt mir 👍 thx'


Anmelden zum Antworten