Templates -> Operatoren überschreiben (Pointer geht nicht)
-
Hallo zusammen,
mir ist leider kein besseres Titel eingefallen

Hier mein Problem. Ich übe gerade etwas mit Templates und schreibe eine Vektorklasse. Der gezeigte Code funktiniert wunderbar mit Objekten, jedoch nicht mit Pointern, aber nur die Operatoren (mehr habe ich noch nicht getestet). Muss ich alle Operatoren extra für Pointer überschreiben oder wo liegt hier der Fehler?
#ifndef VECTOR3_H_ #define VECTOR3_H_ #include <cmath> template<typename T> class Vector3 { public: Vector3(); Vector3(T x, T y, T z); virtual ~Vector3(); T getX() const; T getY() const; T getZ() const; T getLength() const; T scalarProduct(Vector3<T> vec) const; Vector3<T> crossProduct(Vector3<T> vec) const; Vector3<T> getNormalized() const; void setX(T x); void setY(T y); void setZ(T z); void normalize(); void operator+=(Vector3<T>& vec); void operator-=(Vector3<T> vec); void operator/=(T scalar); void operator*=(T scalar); private: T x, y, z; }; //-- Constructors and Destructor template<typename T> Vector3<T>::Vector3() { x = y = z = 0; } template<typename T> Vector3<T>::Vector3(T x, T y, T z) { this->x = x; this->y = y; this->z = z; } template<typename T> Vector3<T>::~Vector3() { } //-- Constructors and Destructor //-- Operators template<typename T> void Vector3<T>::operator +=(Vector3<T>& vec) { this->x += vec.x; this->y += vec.y; this->z += vec.z; } template<typename T> void Vector3<T>::operator -=(Vector3<T> vec) { this->x -= vec.x; this->y -= vec.y; this->z -= vec.z; } template<typename T> void Vector3<T>::operator /=(T scalar) { this->x /= scalar; this->y /= scalar; this->z /= scalar; } template<typename T> void Vector3<T>::operator *=(T scalar) { this->x *= scalar; this->y *= scalar; this->z *= scalar; } //-- Operators //-- Methods template<typename T> T Vector3<T>::getX() const { return x; } template<typename T> T Vector3<T>::getY() const { return y; } template<typename T> T Vector3<T>::getZ() const { return z; } template<typename T> void Vector3<T>::setX(T x) { this->x = x; } template<typename T> void Vector3<T>::setY(T y) { this->y = y; } template<typename T> void Vector3<T>::setZ(T z) { this->z = z; } template<typename T> void Vector3<T>::normalize() { this->x /= getLength(); this->y /= getLength(); this->z /= getLength(); } template<typename T> T Vector3<T>::getLength() const { return sqrt(this->x * this->x + this->y * this->y + this->z * this->z); } template<typename T> T Vector3<T>::scalarProduct(Vector3<T> vec) const { return this->x * vec.x + this->y * vec.y + this->z * vec.z; } template<typename T> Vector3<T> Vector3<T>::crossProduct(Vector3<T> vec) const { Vector3<T> crossProduct( this->y * vec.z - this->z * vec.y, this->z * vec.x - this->x * vec.z, this->x * vec.y - this->y * vec.x); return crossProduct; } template<typename T> Vector3<T> Vector3<T>::getNormalized() const { Vector3<T> normalizedVec(this->x, this->y, this->z); normalizedVec /= getLength(); return normalizedVec; } //-- Methods #endif /* VECTOR3_H_ */void printVec(Vector3<float>* vec) { std::cout << "X: " << vec->getX() << "\tY: " << vec->getY() << "\tZ: " << vec->getZ() << std::endl; } int main() { Vector3<float>* vec = new Vector3<float>(1, 2, 3); Vector3<float>* vec2 = new Vector3<float>(-7, 8, 9); printVec(vec); vec += vec2; printVec(vec); vec->normalize(); printVec(vec); delete vec; delete vec2; return 0; }Als Fehler bekomme ich:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o Main.o "..\\Main.cpp" ..\Main.cpp: In function 'int main()': ..\Main.cpp:20:9: error: invalid operands of types 'Vector3<float>*' and 'Vector3<float>*' to binary 'operator+' ..\Main.cpp:20:9: error: in evaluation of 'operator+=(class Vector3<float>*, class Vector3<float>*)'
-
Muss ich alle Operatoren extra für Pointer überschreiben oder wo liegt hier der Fehler?
Du kannst Operatoren nur für User-definierte Datentypen überladen, also für Klassen.
Vector3<float>* vec = new Vector3<float>(1, 2, 3); Vector3<float>* vec2 = new Vector3<float>(-7, 8, 9);Wieso benutzt du überhaupt Heapobjekte, bzw. Zeiger?
Das macht hier überhaupt keinen Sinn.Irgendwie verwirrt mich das, denn wer benutzt Templates - kann aber absolute Grundlagen nicht?
-
Vector3<float> vec(1, 2, 3); Vector3<float> vec2(-7, 8, 9);Wie kommst du denn auf die Idee, new zu nutzen?
In dem Code sind wahrscheinlich noch mehr Fehler, der Code sieht nicht vertrauenserweckend aus. Aus dem Internet zusammenkopiert und angepasst? Nicht böse sein, falls dies nicht der Fall sein sollte, es sieht eben einfach so aus, als hättest du nicht wirklich verstanden, was du da tust. Was irgendwie komisch ist, da hier teilweise durchaus fortgeschrittene Sprachmittel benutzt werden.
edit: Oh, viel zu langsam. Aber ich bin anscheinend mal absolut einer Meinung mit Sone
.
-
du musst die Zeiger erst dereferenzieren, ansonsten werden die in der Klasse definierten operatoren vom Compiler nicht beachtet.
statt:
vec += vec2;so:
*vec += *vec2;@Sone: das mit dem Zeigern im Beispielprogramm ist vermutlich nur zum testen...
-
firefly schrieb:
@Sone: das mit dem Zeigern im Beispielprogramm ist vermutlich nur zum testen...
Was sollte man damit testen wollen? Ich bin da skeptisch. Hier kommen viel zu oft ehemalige Javaprogrammierer vorbei (oder Leute, die von solchen Leuten gelernt haben), die glauben, new wäre in C++ der normale Weg, Objekte zu erstellen. Zumal macht ein new mit dem zugehörigen delete im gleichen Scope keinen Sinn, bringt aber erhebliche technische Nachteile. Und ist komplizierter. Und es ist zusätzlich noch ein potentielles Speicherloch, da Code dazwischen (hier z.B. das zweite new) eine Exception werfen könnte und das delete dann nie ausgeführt wird.
-
Sone schrieb:
Wieso benutzt du überhaupt Heapobjekte, bzw. Zeiger?
Das macht hier überhaupt keinen Sinn.Irgendwie verwirrt mich das, denn wer benutzt Templates - kann aber absolute Grundlagen nicht?
Grundlagen existieren. Anscheinend nicht genug. Genau aus diesem Grund habe ich die Klasse geproggt um die Zusammenhänge und Funktionsweisen des verwendeten Codes zu verstehen.
firefly schrieb:
@Sone: das mit dem Zeigern im Beispielprogramm ist vermutlich nur zum testen...
Du hast es erfasst.

Und der ist nicht aus dem Internet zusammengeschustert :P. Ich habe lediglich meine Kenntnisse bezüglich linearer Algebra aufgefrischt ^^
Gibt es eine Möglichkeit die Klasse so umzuschreiben, dass ich sie für Pointer und Objekte benutzen kann und *´s und &´s zu verwenden?
-
SeppJ schrieb:
firefly schrieb:
@Sone: das mit dem Zeigern im Beispielprogramm ist vermutlich nur zum testen...
Was sollte man damit testen wollen? Ich bin da skeptisch. Hier kommen viel zu oft ehemalige Javaprogrammierer vorbei (oder Leute, die von solchen Leuten gelernt haben), die glauben, new wäre in C++ der normale Weg, Objekte zu erstellen...
Verdammt...erwischt. Ich komme wirklich aus der Java-Ecke ^^
-
aptem schrieb:
SeppJ schrieb:
firefly schrieb:
@Sone: das mit dem Zeigern im Beispielprogramm ist vermutlich nur zum testen...
Was sollte man damit testen wollen? Ich bin da skeptisch. Hier kommen viel zu oft ehemalige Javaprogrammierer vorbei (oder Leute, die von solchen Leuten gelernt haben), die glauben, new wäre in C++ der normale Weg, Objekte zu erstellen...
Verdammt...erwischt. Ich komme wirklich aus der Java-Ecke ^^
Dann musst du dir nur eine verdammte Sache merken: Selber Speicher verwalten ist in C++ völlig Tabu. Daher vermeide jegliches
new.Aber ich bin anscheinend mal absolut einer Meinung mit Sone
.Erstes und letztes mal.

-
Gibt es trotzdem Lösung für mein Problem wo ich die *´s und &´s weglassen kann?
-
aptem schrieb:
Gibt es trotzdem Lösung für mein Problem wo ich die *´s und &´s weglassen kann?
Stackobjekte benutzen? :xmas2:
-
aptem schrieb:
Gibt es trotzdem Lösung für mein Problem wo ich die *´s und &´s weglassen kann?
Das ist keine günstige Frage. * und & kann in C++ je nach Zusammenhang sehr, sehr unterschiedliche Bedeutungen haben. Wenn du wissen willst, wie das ohne Pointer geht: Lass sie einfach weg! Wir sind hier alle verwundert, wieso du sie überhaupt benutzt. Insbesondere sind deine '&' in deinem Programm keine Adressoperatoren, sondern markieren Referenzen. Das ist ganz was anderes und völlig ok.
-
Ok, danke für eure Hilfe und Ratschläge. Dann werde ich in Zukunft (wenn es geht) auf Pointer verzichten.
