+= Operator richtig überladen
-
Hallo,
ich soll für die Uni eine Klasse für 3 dimensionale Vektoren mit entsprechenden Operatoren schreiben. Mein Frage ist ob das was ich geschrieben habe richtig ist und wenn nicht warum es so falsch ist. Vielleicht kann ja jemand der mehr Erfahrung damit hat mal drüber schauen und es mir erklären.
#ifndef VECTOR_H #define VECTOR_H #include <math.h> class Vector3{ float x = 0.0f; float y = 0.0f; float z = 0.0f; public: //Konstruktor Vector3(); Vector(float x, float y, float z){ x = x; y = y; z = z; } //Deskruktor ~Vektor3(); //Addition const void operator += (const Vector3 &vec){ x = x + vec.x; y = y + vec.y; z = z + vec.z; } const Vector3 operator + (const Vector3 &vec){ Vector3 dummy = new Vector3(); dummy.x = x + vec.x; dummy.y = y + vec.y; dummy.z = z + vec.z; return dummy; } //Subtraktion Vector3 operator -= (const Vector3 &vec); Vector3 operator - (const Vector3 &vec); //Multiplikation Vector3 operator *= (float num); }greetz
floetentheo
-
-
const Vector3 operator + (const Vector3 &vec){ Vector3 dummy = new Vector3(); dummy.x = x + vec.x; dummy.y = y + vec.y; dummy.z = z + vec.z; return dummy; }da stimmt nix, aber garnix ^^ new braucht ein delete, new ist Heap, der Rest deines Codes sieht aber nach Stack aus... usw.
-
Da ich leider noch nicht in C++ denken kann sagt mir das überhaupt nix.
Ist der += Operator richtig so wie ich ihn geschrieben habe?
Und was ist denn genau falsch an dem + Operator?
-
stimmt, ich denke, du solltest dir erst mal Grundlagen über Stack und Heap ansehen. Das hat was mit Speicherbereichen zu tun.
Da gibts später sogar noch interessante dinge.
z.B Weil Stack und Heap sich entgegenwachsen gibt's Overflows usw... und gerade in der Programmierung ist Stack&Heap wichtig. Schon wenn du Variablen global deklarierst anstatt in der int main...
-
//Addition const Vector3& operator += (const Vector3 &vec){ x = x + vec.x; y = y + vec.y; z = z + vec.z; return *this; }So wird das gemacht. erspart dir vieles und vec3 = vec3 + vec3; is damit auch möglich. Wobei operator+ mit void nicht erlaubt ist, nach ansi. Wenn du den Code mit g++ und der Einstellung --ansi kompilierst, bekommst du Fehler.
const Vector3 operator + (const Vector3 &vec){ Vector3 dummy = new Vector3(); dummy.x = x + vec.x; dummy.y = y + vec.y; dummy.z = z + vec.z; return dummy; } }Was du hier machst ist völlig falsch. new initialisiert einen Speicherbereich für Vector3 auf einen Zeiger. Wenn du eine Instanz der Klasse erstellen willst, reicht
Vector3 dummy; // Richtig wäre btw Vector3* dummy = new Vector3;Richtig wird so überladen:
Vector3& operator += (const Vector3& vec) { z += vec.z; x += vec.x; y += vec.y; return *this; }float x = 0.0f; float y = 0.0f; float z = 0.0f;Ist auch falsch. Initialisert wird im Constructor.
Vector3::Vector3() { x = 0; y = 0; z = 0; }Zur Veranschaulichung einer meiner Vektoren. Lass dich vom Template nicht iritieren, ersetze das T in Gedanken einfach mit float oder int.

/********************************************************* * File : dtVector3.h * Author : D. Gentner * Date : 2006/10/20 * Purpose: A 3D-Vector for math-operations. * Todo : * * License: Public Domain *********************************************************/ #ifndef _DTVECTOR3_H_ #define _DTVECTOR3_H_ /** \brief This is a simple Template for a 3 Dimensional Vector. */ template <typename T> class dtVector3 { public: inline dtVector3(){ m_x = m_y = m_z = 0; } inline ~dtVector3(){} /** \brief Set-Constructor */ inline dtVector3(T _x, T _y, T _z) { m_x=_x; m_y=_y; m_z=_z; } /** \brief Copy-Constructor */ inline dtVector3(const dtVector3& v) { m_y = v.getX(); m_y = v.getY(); m_z = v.getZ(); } /** \brief Setter */ void setX(const T _x){ m_x = _x; } /** \brief Setter */ void setY(const T _y){ m_y = _y; } /** \brief Setter */ void setZ(const T _z){ m_z = _z; } /** \brief Setter */ void set(const dtVector3<T>& t){ m_x = t.getX(); m_y = t.getY(); m_z = t.getZ(); } void set(const T x, const T y, const T z){ m_x = x; m_y=y;m_z=z;}; /** \brief Getter */ T getX()const { return m_x; } /** \brief Getter */ T getY()const { return m_y; } /** \brief Getter */ T getZ()const { return m_z; } /** \brief Getter */ dtVector3<T> get()const { return *this; } /** \brief Overloaded = operator */ inline dtVector3<T> operator= ( const dtVector3<T>& v) { m_x = v.getX(); m_y = v.getY(); m_z = v.getZ(); return *this; } /** \brief Overloaded = operator */ inline dtVector3<T> operator= ( const T& v) { m_x = m_y = m_z = v; return *this; } /** \brief Overloaded ++ postfix operator */ inline const dtVector3<T> operator++(int) { dtVector3<T> tmp= *this; m_x++; m_y++; m_z++; return tmp; } /** \brief Overloaded ++ prefix operator */ inline dtVector3<T> operator++() { m_x++; m_z++; m_y++; return *this; } /** \brief overloaded + operator */ inline dtVector3<T> operator+(const T v) { return dtVector3<T>(m_x+v, m_y+v, m_z+v); } /** \brief overloaded + operator */ inline dtVector3<T> operator+(const dtVector3<T>& v) { return dtVector3<T>(m_x+v.getX(), m_y+v.getY(), m_z+v.getZ()); } /** \brief overloaded += operator */ inline dtVector3<T> operator+= (const dtVector3<T>& v) { return dtVector3<T>(m_x+=v.getX(), m_y+=v.getY(), m_z+=v.getZ()); } /** \brief overloaded += operator */ inline dtVector3<T> operator+= (const T v) { return dtVector3<T>(m_x+=v, m_y+=v, m_z+=v); } /** \brief Overloaded -- postfix operator */ inline const dtVector3<T> operator--(int) { dtVector3<T> tmp= *this; m_x--; m_y--; m_z--; return tmp; } /** \brief Overloaded -- prefix operator */ inline dtVector3<T> operator--() { m_x--; m_z--; m_y--; return *this; } /** \brief overloaded - operator */ inline dtVector3<T> operator- ( const dtVector3<T>& v) { return dtVector3<T>(m_x-v.getX(),m_y-v.getY(),m_z-v.getZ()); } /** \brief overloaded - operator */ inline dtVector3<T> operator- ( const T v) { return dtVector3<T>(m_x-v, m_y-v, m_z-v); } /** \brief overloaded -= operator */ inline dtVector3<T> operator-= (const dtVector3<T>& v) { return dtVector3<T>(m_x-=v.getX(),m_y-=v.getY(),m_z-=v.getZ()); } /** \brief overloaded -= operator */ inline dtVector3<T> operator-= (const T v) { return dtVector3<T>(m_x-=v,m_y-=v,m_z-=v); } /** \brief overloaded * operator */ inline dtVector3<T> operator* (const dtVector3<T>& v) { return dtVector3<T>(m_x*v.getX(), m_y*v.getY(), m_z*v.getZ()); } /** \brief overloaded * operator */ inline dtVector3<T> operator* (const T v) { return dtVector3<T>(m_x*v, m_y*v, m_z*v); } /** \brief overloaded *= operator */ inline dtVector3<T> operator*= (const dtVector3<T>& v) { return dtVector3<T>(m_x*=v.getX(), m_y*=v.getY(), m_z*=v.getZ()); } /** \brief overloaded *= operator */ inline dtVector3<T> operator*= (const T v) { return dtVector3<T>(m_x*=v, m_y*=v, m_z*=v); } /** \brief overloaded / operator */ inline dtVector3<T> operator/ (const dtVector3<T>& v) { return dtVector3<T>(m_x/v.getX(),m_y/v.getY(),m_z/v.getZ()); } /** \brief overloaded / operator */ inline dtVector3<T> operator/ (const T v) { return dtVector3<T>(m_x/v,m_y/v,m_z/v); } /** \brief overloaded /= operator */ inline dtVector3<T> operator/= (const dtVector3<T>& v) { return dtVector3<T>(m_x/=v.getX(),m_y/=v.getY(),m_z/=v.getZ()); } /** \brief overloaded / operator */ inline dtVector3<T> operator/= (const T v) { return dtVector3<T>(m_x/=v,m_y/=v,m_z/=v); } /** \brief overloaded == operator */ inline bool operator== (const dtVector3& v) { return ( m_x == v.getX() && m_y == v.getY() && m_z == v.getZ() ); } /** \brief overloaded < operator */ inline bool operator< ( const dtVector3<T>& v) { return ( m_x < v.getX() && m_y < v.getY() && m_z < v.getZ() ); } /** \brief overloaded > operator */ inline bool operator> ( const dtVector3<T>& v) { return ( m_x > v.getX() && m_y > v.getY() && m_z > v.getZ() ); } /** \brief overloaded [] operator * * * Please make sure that you only use values from 0-2, where * 0 = x, 1 = y, 2 = z. * */ inline T operator[] ( const int index ) { if (index == 0){ return m_x; } else if (index == 1){ return m_y; } else if (index == 2){ return m_z; } else{ #ifdef _DEBUG throw std::runtime_error("dtVector3::operator[]: Index Out of Range!"); #endif return 0; } } private: T m_x, m_y, m_z; }; #endif /* _DTVECTOR3_H_ */HTH
rya.
-
Noch eine Ergänzung zur Beziehung zwischen += und +: Du verwendest zweimal (fast) identischen Code, das erzeugt Redundanzen und bringt die Gefahr, daß du irgendwann nur eine der Funktionen anpasst und die andere vergisst - das würde dazu führen, daß "v+=u;" plötzlich nicht mehr äquivalent zu "v=v+u;" ist. Besser ist es da, den operator+ durch operator+= auszudrücken:
//btw, hier geht auch ein globaler Operator const Vector3D operator+(Vector3D l/*bewußt kein const-ref*/,const Vector3D& r) { l+=r; return l; }@scorcher: Dem Ansi-Standard ist es egal, was die überladenen Operatoren zurückgeben - void-Rückgabe ist "nur" inkonsistent gegenüber dem Verhalten der Build-in Typen.
Und wo wir gerade bei Redundanzen sind - deine Vector-Klasse hat ähnlich redundante Operatoren wie dort oben (z.B. + vs. += oder ++x vs. x++).
-
Viel Dank an Scorcher24, hat wohl doch jemand meine Frage genau gelesen.

Eine Frage hätte ich jedoch noch. Ist der Ausdruck
Vector3& vec;und
Vector3 &vec;vom prinzip her das gleiche?
-
Es ist das selbe.
-
ach schon gut.. sorry
