Template Vector Klasse gemacht (kein problem nur mal zeigen willsch)



  • Hi,

    ich habe eine Template Vector Klasse gebastelt, jaaa 🙂

    Die wollt ich einfach mal so zeigen, ja, einfach mal so:

    #ifndef _CVECTOR_
    #define _CVECTOR_
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> class CVector
    {
    protected:
    	T m_x, m_y, m_z;
    public:
    	CVector()                   {m_x = m_y = m_z = 0.0f;}
    	CVector(T x, T y, T z)  : m_x(x), m_y(y), m_z(z) {}
    
    	 T     getX() const {return m_x;}
    	 T     getY() const {return m_y;}
    	 T     getZ() const {return m_z;}
    
    	 void  setVector(CVector<T> v) {m_x = v.m_x; m_y = v.m_y; m_z = v.m_z;}
    	 void  setVector(T x, T y, T z);
    
    	 CVector<T>  operator-(const CVector<T>&) const;
    	 CVector<T>  operator+(const CVector<T>&) const;
    	 T           operator*(const CVector<T>&) const;
    	 CVector<T>  operator*(T val)      const;
    	 CVector<T>  operator/(T val)      const;
    	 CVector<T>  operator/(const CVector<T>&) const;
    	 CVector<T>  operator=(const CVector<T>&);
    	 CVector<T>  operator-();
    	 const CVector<T>&  operator+=(const CVector<T>&);
    	 const CVector<T>&  operator-=(const CVector<T>&);
    	 const CVector<T>&  operator*=(const CVector<T>&);
    	 const CVector<T>&  operator*=(T);
    	 const CVector<T>&  operator/=(const CVector<T>&);
    	 const CVector<T>&  operator/=(T);
    
    	 CVector<T>  CrossProduct(const CVector<T>&) const;
    	 CVector<T>  Normalize() const;
    
    	 T    Magnitude() const;
    	 T    MagnitudeQuad() const;
    };
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator-(const CVector<T>& a) const
    {
    	return CVector(m_x - a.m_x, m_y - a.m_y, m_z - a.m_z);	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator+(const CVector<T>& a) const
    {
    	return CVector(m_x + a.m_x, m_y + a.m_y, m_z + a.m_z);	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::operator*(const CVector& a) const
    {
    	return m_x * a.m_x + m_y * a.m_y + m_z * a.m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::CrossProduct(const CVector& a) const 
    {
    	return CVector(m_y * a.m_z - m_z * a.m_y,
    				   m_z * a.m_x - m_x * a.m_z,
    				   m_x * a.m_y - m_y * a.m_x);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::Magnitude() const
    {
    	return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::MagnitudeQuad() const
    {
    	return m_x * m_x + m_y * m_y + m_z * m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::Normalize() const
    {
    	T fMag = Magnitude();
    	CVector<T> vec(*this);
    
    	vec /= Magnitude();
    
    	return vec;	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T>  CVector<T>::operator=(const CVector& a)
    {
    	m_x = a.m_x;
    	m_y = a.m_y;
    	m_z = a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator+=(const CVector& a)
    {
    	*this = *this + a;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator-=(const CVector& a)
    {
    	*this = *this - a;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator*(T val) const
    {
    	CVector<T> vec(*this);
    	vec.m_x *= val;
    	vec.m_y *= val;
    	vec.m_z *= val;
    
    	return vec;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator/(T val) const
    {
    	CVector<T> vec(*this);
    	vec.m_x /= val;
    	vec.m_y /= val;
    	vec.m_z /= val;
    
    	return vec;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator*=(const CVector& a)
    {
    	m_x *= a.m_x;
    	m_y *= a.m_y;
    	m_z *= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator*=(T val)
    {
    	m_x *= val;
    	m_y *= val;
    	m_z *= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator/=(T val)
    {
    	m_x /= val;
    	m_y /= val;
    	m_z /= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator/=(const CVector& a)
    {
    	m_x /= a.m_x;
    	m_y /= a.m_y;
    	m_z /= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> void CVector<T>::setVector(T x, T y, T z)
    {
    	m_x = m_x;
    	m_y = m_y;
    	m_z = m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T> CVector<T>::operator-()
    {
    	m_x = -m_x;
    	m_y = -m_y;
    	m_z = -m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #endif
    

    Kommentare, Verbesserungsvorschläge gerne gesehen 🙂

    PS: Wahrscheinlich sind noch net alle Mathematikfunktionen drin, die füge ich dann jeweils bei Bedarf noch ein.

    MfG MAV



  • Warum m_x = m_y = m_z = 0.0f?
    Gibt dann bei CVector<int> v Probleme (warning: argument to `int' from `float')
    Wenn du Langeweile haben solltest, könntest du das ja alles noch n-dimensional gestalten und einen Parser mit einbauen, sodaß man z.B. Vektoren im Maple(TM)-Format übergeben kann...

    Falls ich Unsinn posten sollte, liegt das an einer Überdosis Federweißer 🤡



  • Mis2com´ schrieb:

    Hi,

    template<class T> class CVector
    {
    // Warum nicht private? CVector hat eh keinen virtuellen Destruktor.
    protected:
    	T m_x, m_y, m_z;
    public:
             // Statt 0.0f vielleicht "T()"? Wimni ist das für die eingebauten Typen die jeweilige 0.
    	CVector()                   {m_x = m_y = m_z = 0.0f;}
    	CVector(T x, T y, T z)  : m_x(x), m_y(y), m_z(z) {}
    
    	 T     getX() const {return m_x;}
    	 T     getY() const {return m_y;}
    	 T     getZ() const {return m_z;}
    
              // Wozu? Ist dasselbe wie op=, nur mit Wertparameter...
    	 void  setVector(CVector<T> v) {m_x = v.m_x; m_y = v.m_y; m_z = v.m_z;}
              // Dafür hätte ich hier setX/Y/Z() erwartet.
    
              // Sollten alles Non-Member sein.
    	 CVector<T>  operator-(const CVector<T>&) const;
    	 CVector<T>  operator*(T val)      const;
    	 CVector<T>  operator/(const CVector<T>&) const;
              ...
    
              // Rückgabetyp sollte imho CVector<T>& sein.
    	 CVector<T>  operator=(const CVector<T>&);  
    
              // Warum geben diese Funktionen nur const-Referenzen zurück?
    	 const CVector<T>&  operator+=(const CVector<T>&);
    	 const CVector<T>&  operator-=(const CVector<T>&);
              ...
    };
    

    Ansonsten könntest du vielleicht noch die boost::call_traits benutzen, um die entsprechenden Typen für die Rückgabe, Parameterannahme etc. festzulegen.



  • operator void schrieb:

    Mis2com´ schrieb:

    Hi,

    // Warum nicht private? CVector hat eh keinen virtuellen Destruktor.
    protected:
    	T m_x, m_y, m_z;
    

    Warum nicht public? Hat "C"Vector irgendwelche Invarianten aufrechtzuerhalten? Ist die Implementierung geheim? Warum soviele Memberfunktionen => GOTW #84?



  • Bashar schrieb:

    Warum nicht public?

    ->Information Hiding?

    -junix



  • Und es wäre IMHO noch schön wenn man folgendes machen könnte (intuitiver zu bedienen)

    CVector<int> v(1,2,3);
    CVector<int> w(4,5,6);
    CVector<int> x=2*v+2*w;
    

    Müßte z.B. so gehen:
    friend Vector operator* (double scalar,CVector<T>& vec);
    (Das friend könnte man sich natürlich dank deiner get-Methoden ersparen...)



  • #ifndef _CVECTOR_

    Solche Namen (Unterstrich gefolgt von Großbuchstabe) gehören der Implementation. Du darfst sie nicht verwenden.
    Besser:

    #ifndef CVECTOR_
    

    Oder wenn dir das zu wenig kryptisch ist:

    #ifndef CVECTOR_H__INCLUDED
    

    CVector() {m_x = m_y = m_z = 0.0f;}
    CVector(T x, T y, T z) : m_x(x), m_y(y), m_z(z) {}

    Ich würde stattdessen nur einen Ctor anbieten:

    explicit CVector(T x = T() , T y = T(), T z = T())  : m_x(x), m_y(y), m_z(z) {}
    

    Und dann könnte man natürlich noch gut ein paar Template-Operatoren spendieren.
    Damit man auch einen CVector<int> zu einem CVector<double> addieren kann.



  • junix schrieb:

    Bashar schrieb:

    Warum nicht public?

    ->Information Hiding

    Welche Informationen? Die Koordinaten können durch die öffentliche Schnittstelle abgefragt und gesetzt werden.



  • @Bashar
    Lass einen der Operatoren lazy-Evaluieren und schon würde dir die fehlende Kapselung das Genick brechen.
    Der einzige Grund der imo *derzeit* gegen public spricht ist der, dass *keiner* für public spricht. Und in Zukunft kann sich die Balance noch weiter negativ verschieben. Ein CVektor ist kein std::pair. Da kann immerhin doch ne Menge Komplexität hinzukommen.



  • @Bashar: ...und du nimmst dir jegliche Möglichkeit, nachträglich noch irgendwelche Kontroll od. Synchronisationsmechanismen einzubauen ohne an jedem Stück Code, das diese Klasse verwendet umzubauen... bombige Lösung... zumal der Compiler (bzw. dessen Optimizer) vermutlich sowieso den Aufruf wegoptimiert, wenn man die get-Funktionen noch inline machen würde...

    @Mis2Com: ist das in der Funktion

    template<class T> void CVector<T>::setVector(T x, T y, T z)
    

    absicht?

    -junix

    [edit]mist, zu spät (o;[/edit]



  • HumeSikkins schrieb:

    Ein CVektor ist kein std::pair. Da kann immerhin doch ne Menge Komplexität hinzukommen.

    Da bin ich ja gespannt.



  • @Bashar
    Ok. Ich habe da in meiner mathematischen Genialität gerade mal was verwechselt. Insofern ist mein Einwand wohl sehr künstlich. Ich persönlich würde die Variablen auf jeden Fall erstmal nicht public machen. Ein großes Problem sehe ich darin aber auch nicht. Zumindest nicht, wenn dieses Ding wirklich als plain-vanilla-Vektor gedacht ist.



  • Verdammt, ich wollte das schreiben *bevor* du mich darauf hinweist. Jetzt stehe ich wieder dumm da 😃



  • Mal noch ne Kleinigkeit zur Klasse:

    Sollten die Operatoren wie + und Konsorten nicht lieber const-Objekte zurückgeben?
    Da sonst a-b = c; möglich wird.

    Außerdem finde ich die Idee lustig operator+= mit Hilfe von operator+ und operator= zu implementieren. Ich mach's irgendwie immer andersrum um mir die unnötige(n) Kopie(n) zu sparen.

    MfG Jester



  • btw:

    #ifndef _CVECTOR_ 
    #define _CVECTOR_ 
    // ...
    #endif
    

    Das ist nicht erlaubt. Defines dürfen nicht mit einem Unterstrich beginnen, außer sie sind vom Compiler oder einem compilereigenen Header selbst definiert worden.



  • @cd9000: guck dir mal den erstnen Satz in HumeSikkins Antwort an 🙂



  • Ups. Hab ich wohl übersehen. 🙄

    Aber wie so oft: Doppelt hält besser. 🙂
    Denn wetten, er hat es immer noch nicht geändert?



  • Hi, hab mich lang netmehr gemeldet. 🙂

    Gut also das mit 0.0f habsch gelöst.

    Da sonst a-b = c; möglich wird.

    OK, mom, korrigiere ich auch noch.

    protected ist immer gut, weil ich jedem erlaube, meine Klassen zu erben: 😃

    Virtueller Destruktor?
    Hm, ok, bau ich dann noch ein...

    (ok hier alles net wirklcih sinnvoll aber egal :P)

    template<class T> void CVector<T>::setVector(T x, T y, T z)

    Was soll daran Absicht sein?

    Ich meine, :D, was soll daran komischerweise Absicht sein? 🙂

    boost::call_traits

    Wasn das? 🙂

    OK, hier mal eine etwas überarbeitete Version:

    #ifndef CVECTOR_
    #define CVECTOR_
    
    #include <d3d9.h>
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> class CVector
    {
    protected:
    	T m_x, m_y, m_z;
    public:
    	CVector(T x = T(), T y = T(), T z = T())  : m_x(x), m_y(y), m_z(z) {}
    
    	 T     getX()    const {return m_x;}
    	 T     getY()    const {return m_y;}
    	 T     getZ()    const {return m_z;}
    	 void  setX(T t)       {m_x = t;}
    	 void  setY(T t)       {m_y = t;}
    	 void  setZ(T t)       {m_z = t;}
    
    	 void  setVector(T x, T y, T z);
    	 D3DVECTOR getD3DVECTOR();
    
    	 const CVector<T>  operator-(const CVector<T>&) const;
    	 const CVector<T>  operator+(const CVector<T>&) const;
    	 T           operator*(const CVector<T>&) const;
    	 CVector<T>  operator*(T val)      const;
    	 CVector<T>  operator/(T val)      const;
    	 CVector<T>  operator/(const CVector<T>&) const;
    	 CVector<T>& operator=(const CVector<T>&);
    	 CVector<T>  operator-();
    	 CVector<T>&  operator+=(const CVector<T>&);
    	 CVector<T>&  operator-=(const CVector<T>&);
    	 CVector<T>&  operator*=(const CVector<T>&);
    	 CVector<T>&  operator*=(T);
    	 CVector<T>&  operator/=(const CVector<T>&);
    	 CVector<T>&  operator/=(T);
    
    	 CVector<T>  CrossProduct(const CVector<T>&) const;
    	 CVector<T>  Normalize() const;
    
    	 T    Magnitude() const;
    	 T    MagnitudeQuad() const;
    
    	 virtual CVector<T> {};
    };
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator-(const CVector<T>& a) const
    {
    	return CVector(m_x - a.m_x, m_y - a.m_y, m_z - a.m_z);	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator+(const CVector<T>& a) const
    {
    	return CVector(m_x + a.m_x, m_y + a.m_y, m_z + a.m_z);	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::operator*(const CVector& a) const
    {
    	return m_x * a.m_x + m_y * a.m_y + m_z * a.m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::CrossProduct(const CVector& a) const 
    {
    	return CVector(m_y * a.m_z - m_z * a.m_y,
    				   m_z * a.m_x - m_x * a.m_z,
    				   m_x * a.m_y - m_y * a.m_x);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::Magnitude() const
    {
    	return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::MagnitudeQuad() const
    {
    	return m_x * m_x + m_y * m_y + m_z * m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::Normalize() const
    {
    	T fMag = Magnitude();
    	CVector<T> vec(*this);
    
    	vec /= Magnitude();
    
    	return vec;	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T>  CVector<T>::operator=(const CVector& a)
    {
    	m_x = a.m_x;
    	m_y = a.m_y;
    	m_z = a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator+=(const CVector& a)
    {
    	*this = *this + a;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator-=(const CVector& a)
    {
    	*this = *this - a;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator*(T val) const
    {
    	CVector<T> vec(*this);
    	vec.m_x *= val;
    	vec.m_y *= val;
    	vec.m_z *= val;
    
    	return vec;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator/(T val) const
    {
    	CVector<T> vec(*this);
    	vec.m_x /= val;
    	vec.m_y /= val;
    	vec.m_z /= val;
    
    	return vec;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator*=(const CVector& a)
    {
    	m_x *= a.m_x;
    	m_y *= a.m_y;
    	m_z *= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator*=(T val)
    {
    	m_x *= val;
    	m_y *= val;
    	m_z *= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator/=(T val)
    {
    	m_x /= val;
    	m_y /= val;
    	m_z /= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T>& CVector<T>::operator/=(const CVector& a)
    {
    	m_x /= a.m_x;
    	m_y /= a.m_y;
    	m_z /= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> void CVector<T>::setVector(T x, T y, T z)
    {
    	m_x = m_x;
    	m_y = m_y;
    	m_z = m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T> CVector<T>::operator-()
    {
    	m_x = -m_x;
    	m_y = -m_y;
    	m_z = -m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> D3DVECTOR CVector<T>::getD3DVECTOR()
    {
    	D3DVECTOR v;
    	v.x = m_x;
    	v.y = m_y;
    	v.z = m_z;
    
    	return v;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #endif
    

    Ist eigentlich für meine 3D Engine gedacht, daher die Hiflsmethode und die Headerinkludierung.
    Kann man ja rausmachen, wenn mans halt net nutzt. 🙄

    Naja, ist eigentlich meine erste Klasse, die Operatoren richtig nutzt und auch meine erste Templateklasse. 😃



  • Normalerweise haben die Operatoren +=, -=, ... den Vorteil keine überflüssigen Temporären Objekte zu erzeugen. Deine Variante verwendet aber intern +, -, ... und erzeugt somit viel overhead, der nicht nötig ist.

    template<class T> inline const CVector<T>& CVector<T>::operator+=(const CVector& a) 
    { 
        m_x += a.m_x; 
        m_y += a.m_y; 
        m_z += a.m_z; 
    
        return *this; 
    } 
    
    // den würde ich zwar eh nicht als Methode machen, aber egal
    template<class T> inline const CVector<T> CVector<T>::operator+(const CVector& a) 
    { 
        CVector<T> temp(*this);
    
        return temp += a;
    }
    

    Und dann das:

    template<class T> inline CVector<T> CVector<T>::Normalize() const 
    { 
        T fMag = Magnitude(); 
        CVector<T> vec(*this); 
    
        vec /= Magnitude(); 
    
        return vec;     
    }
    

    Muss man das verstehen? wofür wird fMag angelegt? was bedeutet das Präfix f?
    Und bei "Normalize" erwarte ich, dass der Vektor selbst normalisiert wird, nicht dass ich eine normalisierte Kopie erhalte. Denk mal über den Namen nach.

    /edit siehe Jesters post (kommt vom copy und paste)



  • #ifndef CVECTOR_
    #define CVECTOR_
    
    #include <d3d9.h>
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> class CVector
    {
    protected:
    	T m_x, m_y, m_z;
    public:
    	CVector(T x = T(), T y = T(), T z = T())  : m_x(x), m_y(y), m_z(z) {}
    
    	 T     getX()    const {return m_x;}
    	 T     getY()    const {return m_y;}
    	 T     getZ()    const {return m_z;}
    	 void  setX(T t)       {m_x = t;}
    	 void  setY(T t)       {m_y = t;}
    	 void  setZ(T t)       {m_z = t;}
    
    	 void  setVector(T x, T y, T z);
    	 D3DVECTOR getD3DVECTOR();
    
    	 const CVector<T>  operator-(const CVector<T>&) const;
    	 const CVector<T>  operator+(const CVector<T>&) const;
    	 T           operator*(const CVector<T>&) const;
    	 CVector<T>  operator*(T val)      const;
    	 CVector<T>  operator/(T val)      const;
    	 CVector<T>  operator/(const CVector<T>&) const;
    	 CVector<T>& operator=(const CVector<T>&);
    	 CVector<T>  operator-();
    	 CVector<T>&  operator+=(const CVector<T>&);
    	 CVector<T>&  operator-=(const CVector<T>&);
    	 CVector<T>&  operator*=(const CVector<T>&);
    	 CVector<T>&  operator*=(T);
    	 CVector<T>&  operator/=(const CVector<T>&);
    	 CVector<T>&  operator/=(T);
    
    	 CVector<T>  CrossProduct(const CVector<T>&) const;
    	 CVector<T>  Normalize();
    
    	 T    Magnitude() const;
    	 T    MagnitudeQuad() const;
    
    	 virtual ~CVector<T>() {};
    };
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T> CVector<T>::operator-(const CVector<T>& a) const
    {
    	CVector<T> vec(*this);
    
    	return vec -= a;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline const CVector<T> CVector<T>::operator+(const CVector<T>& a) const
    {
    	return CVector(m_x + a.m_x, m_y + a.m_y, m_z + a.m_z);	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::operator*(const CVector& a) const
    {
    	return m_x * a.m_x + m_y * a.m_y + m_z * a.m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::CrossProduct(const CVector& a) const 
    {
    	return CVector(m_y * a.m_z - m_z * a.m_y,
    				   m_z * a.m_x - m_x * a.m_z,
    				   m_x * a.m_y - m_y * a.m_x);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::Magnitude() const
    {
    	return static_cast<T>(sqrt(m_x * m_x + m_y * m_y + m_z * m_z));
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> T CVector<T>::MagnitudeQuad() const
    {
    	return static_cast<T>(m_x * m_x + m_y * m_y + m_z * m_z);
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator/=(const CVector& a)
    {
    	m_x /= a.m_x;
    	m_y /= a.m_y;
    	m_z /= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::Normalize()
    {
    	return (*this) /= Magnitude();	
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T>& CVector<T>::operator=(const CVector& a)
    {
    	m_x = a.m_x;
    	m_y = a.m_y;
    	m_z = a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator+=(const CVector& a)
    {
    	m_x += a.m_x;
    	m_y += a.m_y;
    	m_z += a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator-=(const CVector& a)
    {
    	m_x -= a.m_x;
    	m_y -= a.m_y;
    	m_z -= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator*(T val) const
    {
    	CVector<T> vec(*this);
    
    	return vec *= val;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T> CVector<T>::operator/(T val) const
    {
    	CVector<T> vec(*this);
    
    	return vec /= val;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator*=(const CVector& a)
    {
    	m_x *= a.m_x;
    	m_y *= a.m_y;
    	m_z *= a.m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator*=(T val)
    {
    	m_x *= val;
    	m_y *= val;
    	m_z *= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> inline CVector<T>& CVector<T>::operator/=(T val)
    {
    	m_x /= val;
    	m_y /= val;
    	m_z /= val;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> void CVector<T>::setVector(T x, T y, T z)
    {
    	m_x = m_x;
    	m_y = m_y;
    	m_z = m_z;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> CVector<T> CVector<T>::operator-()
    {
    	m_x = -m_x;
    	m_y = -m_y;
    	m_z = -m_z;
    
    	return *this;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    template<class T> D3DVECTOR CVector<T>::getD3DVECTOR()
    {
    	D3DVECTOR v;
    	v.x = m_x;
    	v.y = m_y;
    	v.z = m_z;
    
    	return v;
    }
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #endif
    

Anmelden zum Antworten