Template Klasse CMatrix (Typ(4/4))



  • OK, static verwende ich nicht merh...

    template<class T> CVector<T> CVector<T>::operator-()
    {
    	CVector<T> temp(*this);
    	temp.m_x = -m_x;
    	temp.m_y = -m_y;
    	temp.m_z = -m_z;
    
    	return temp;
    }
    

    Ist das nicht korrekt?

    MfF MAV



  • Doch, das stimmt, ist aber nicht sonderlich schnell, warum konstruieren+zuweisen, wenn Du schon einen passenden Konstruktor hast?

    template<class T> const CVector<T> CVector<T>::operator-()
    {
    return CVector<T>(-m_x, -m_y, -m_z);
    }

    tut es doch auch.
    Rückgabewert sollte außerdem konnst sein, da man dem Wert sonst was zuweisen kann und das ist nicht sinnvoll!

    Achja, Dein operator* der Matrix ist mal wieder nicht mit Hilfe des operator*= implementiert. Tippst Du gerne viel?

    MfG Jester



  • Dem Ersteren sitmme ich zu.

    Aber wenn ich einfach nur CMatrix zurückgebe, ist das doch dann eine Kopie, die man auch verändern darf, oder?

    Und beim Letzteren... ich bin mir einfach nicht sicher, ob man das so machen kann i.d.F.

    MfG MAV



  • Naja,

    -v=blablabla ist halt nicht sinnig, daher sollte es konst sein.
    Man sollte sich beim Entwurf immer int als Vorbild nehmen, ist etwas bei ints erlaubt, dann sollte man es auch erlauben, erlauben es die ints nicht, dann sollte man es auch nicht machen, oder kurz: "do as the ints do"

    a+b=c ist mit ints verboten, also sollte eine selbst geschriebene klasse das auch nicht zulassen. Das macht die Benutzung Deiner Klassen intuitiver.

    und die operatoren mit Hilfe anderer zu implementieren ist fast immer möglich!

    Erst Kopie anlegen, dann mit dieser die Operation ausführen, Kopie zurückgeben:

    template<class T> const CMatrix<T> CMatrix<T>::operator*(const CMatrix<T>& m) const 
    { 
       CMatrix<T> temp(*this); // Copy-Konstruktor
       temp*=m;                // operator*=, der macht keine Kopien und so
       return temp;    
    }
    

    Der Vorteil ist: wenn Du operator*= einmal richtig hast, dann haste auch den operator* gleich mit richtig und denken mußte auch nix mehr dabei.

    MfG Jester



  • Ja, ich dachte aber folgendes (das mit const ist jetzt glaube ich ich klar; danke :))

    CMatrix& CMatrix::operator*=(const CMatrix& m)
    {
    	CMatrix temp;
    
    	for(unsigned short i = 0; i < 4; ++i)
    		for(unsigned short j = 0; j < 4; ++j)
    			for(unsigned short k = 0; k < 4; ++k)
    				temp.m_data[j][i] += m_data[k][i] * m.m_data[j][k];
    	return (*this = temp);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    const CMatrix CMatrix::operator*(const CMatrix& m) const
    {
    	CMatrix temp;
    
    	for(unsigned short i = 0; i < 4; ++i)
    		for(unsigned short j = 0; j < 4; ++j)
    			for(unsigned short k = 0; k < 4; ++k)
    				temp.m_data[j][i] += m_data[k][i] * m.m_data[j][k];
    	return temp;
    }
    

    Wennn ich jetzt in * den Operator *= verwende, dann legt er insgesamt 2 temporäre Variablen an, nämlich in * und in *=

    Diese Variante müsste daher IMHO schneller sein, oder?

    MfG MAV



  • Okay, das sehe ich ein. Dennoch solltest Du den Code nicht zweimal schreiben!
    Wie wäre es mit einem privaten Member

    void Multiply(const CVector<T> & A, const CVector<T> & B, CVector<T> & Erg)
    {
       // Code berechnet A*B und schreib in Erg rein.
    }
    
    operator*
    {
       // temp anlegen
       Multiply(A,B, temp);
       return temp;
    }
    
    operator *=
    {
       // temp anlegen
       Multilply(*this, A, temp);
       *this = temp;
    }
    

    Bei Multiply muß man halt aufpassen, daß temp wirklich von A und B verschieden ist, sonst knallt es, aber die Funktion ist ja privat, daher ist es nicht so shlimm.



  • Oder halt in *= schreiben "*this = *this * matrix2;".



  • Jo, aber das ist wohl eher unüblich. Normalerweise macht man eher * mit *=.
    Andersrum hab ich's bis jetzt nur bei Mis2Com's CVector gesehen...



  • Jester schrieb:

    Normalerweise macht man eher * mit *=.

    Weil man *= oft in-place machen kann. Das klappt bei der Matrix leider nicht ...



  • in der multiply() sache darf man nur nicht vergessen zu testen ob

    A||B == Erg sind an sonsten gibt es ein Drama.



  • Ach ich lass es jetzt einfach mal so, dieser kleine Schönheitsfehler ist IMHO zu verkraften 🙂

    Danke für euer aller Hilfe.

    Das war eben meine zweite Templateklasse, vorher hab ich die Dinger netmal angerührt. 🙂

    Jetzt bin ich besser informiert, thx.

    MfG MAV 🙂


Anmelden zum Antworten