Noch eine Frage zu enum



  • Ich habe hier 2 Klassen Point3D und Vector3D. Beide haben ja die gleiche Anzahl von Elementen, nämlich 3. Wie kann ich hier ein enum erstellen welches nur diese beiden Klassen kennen und auch den friend operatoren bekannt ist?

    Mein Problem ist, wenn ich die enums wie hier definiere können die überladenen friend-operatoren nicht darauf zugreifen.

    Klasse Point3D

    #ifndef POINT3D_H_
    #define POINT3D_H_
    
    template<class T> class Point3D {
    
        private:
            //-(Variablen)----------------------------------------------------------
            T n[3]; // x, y, z
            enum {X, Y, Z};
    
        public:
    
            //-(Konstruktoren)------------------------------------------------------
            inline Point3D(); // Punkt mit (0,0,0)
            ...
    };
    #endif
    

    Klasse Vector3D

    #ifndef VECTOR3D_H_
    #define VECTOR3D_H_
    
    #include "point3d.h"
    
    template<class T> class Vector3D {
    
        private:
            //-(Variablen)----------------------------------------------------------
            T n[3]; // x, y, z
            enum {X, Y, Z};
    
        public:
    
            //-(Konstruktoren)------------------------------------------------------
            inline Vector3D(); // Vektor mit (0,0,0)
            inline Vector3D(const T x, const T y, const T z); // Vektor mit (x,y,z)
            inline Vector3D(const Vector3D<T>& v); // Vektor mit (v.x, v.y, v.z)
            inline Vector3D(const Point3D<T> a, const Point3D<T> b); // Erstellt einen Vektor der von a nach b zeigt.
    
            //-(Überladene Operatoren)----------------------------------------------
            inline T& operator[] (int i);
            inline T operator[] (int i) const;
    
            inline Vector3D<T> operator+=(Vector3D<T> v);
            inline Vector3D<T> operator-=(Vector3D<T> v);
            inline Vector3D<T> operator*=(T s);
            inline Vector3D<T> operator/=(T s);
    
            inline Vector3D<T> operator+(); // keine notwendige Funktion
            inline Vector3D<T> operator-(); // Invertierung
    
            friend Vector3D<T> operator+  <>(Vector3D<T> a, Vector3D<T> b);
            friend Vector3D<T> operator-  <>(Vector3D<T> a, Vector3D<T> b);
            friend Vector3D<T> operator*  <>(T s, Vector3D<T> v);
            friend Vector3D<T> operator*  <>(Vector3D<T> v, T s);
            friend Vector3D<T> operator/  <>(Vector3D<T> v, T s);
            friend T           operator*  <>(Vector3D<T> a, Vector3D<T> b);
            friend Vector3D<T> operator^  <>(Vector3D<T> a, Vector3D<T> b);
    
            friend bool        operator== <>(Vector3D<T> a, Vector3D<T> b);
            friend bool        operator!= <>(Vector3D<T> a, Vector3D<T> b);
    
            //-(Methoden)-----------------------------------------------------------
            inline T* array(void) const; // Gibt einen Pointer auf das Array zurück
            inline T norm(void) const; // Berechnet die Norm |x²+y²+z²|
            inline T length(void) const; // Berechnet die Länge sqrt(x²+y²+z²)
    
    };
    
    #include "vector3d.cpp" // wegen eines Templatebugs in verschiedenen Compilern.
    
    #endif // VECTOR3D_H_
    
    #ifndef VECTOR3D_CPP_
    #define VECTOR3D_CPP_
    
    #include <math.h>
    #include "vector3d.h"
    
    enum {X,Y,Z};
    
    //--(Konstruktoren)-------------------------------------------------------------
    
    template<class T> inline Vector3D<T>::Vector3D() {
        n[Z] = n[Y] = n[X] = 0;
    }
    
    template<class T> inline Vector3D<T>::Vector3D(const T x, const T y, const T z) {
        n[X] = x;
        n[Y] = y;
        n[Z] = z;
    }
    
    template<class T> inline Vector3D<T>::Vector3D(const Vector3D<T>& v) {
        n[X] = v.n[X];
        n[Y] = v.n[Y];
        n[Z] = v.n[Z];
    }
    
    template<class T> inline Vector3D<T>::Vector3D(const Point3D<T> a, const Point3D<T> b) {
        n[X] = b[X] - a[X];
        n[Y] = b[Y] - a[Y];
        n[Z] = b[Z] - a[Z];
    }
    
    //--(Überladene Operatoren)-----------------------------------------------------
    
    template<class T> inline T& Vector3D<T>::operator[] (int i) {
        return n[i];
    }
    
    template<class T> inline T Vector3D<T>::operator[] (int i) const {
        return n[i];
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator+=(Vector3D<T> v) {
        n[X] += v[X];
        n[Y] += v[Y];
        n[Z] += v[Z];
        return *this;
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator-=(Vector3D<T> v) {
        n[X] -= v[X];
        n[Y] -= v[Y];
        n[Z] -= v[Z];
        return *this;
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator*=(T s) {
        n[X] *= s;
        n[Y] *= s;
        n[Z] *= s;
        return *this;
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator/=(T s) {
        T inv = 1.0 / s;
        n[X] *= inv;
        n[Y] *= inv;
        n[Z] *= inv;
        return *this;
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator+() {
        return *this;
    }
    
    template<class T> inline Vector3D<T> Vector3D<T>::operator-() {
        return Vector3D<T>(-x, -y, -z);
    }
    
    template<class T> inline Vector3D<T> operator+ (Vector3D<T> a, Vector3D<T> b) {
        return Vector3D<T>(a[X]+b[X], a[Y]+b[Y], a[Z]+b[Z]);
    }
    
    template<class T> inline Vector3D<T> operator- (Vector3D<T> a, Vector3D<T> b) {
        return Vector3D<T>(a[X]-b[X], a[Y]-b[Y], a[Z]-b[Z]);
    }
    
    template<class T> inline Vector3D<T> operator* (T s, Vector3D<T> v) {
        return Vector3D<T>(s*v[X], s*v[Y], s*v[Z]);
    }
    
    template<class T> inline Vector3D<T> operator* (Vector3D<T> v, T s) {
        return Vector3D<T>(s*v[X], s*v[Y], s*v[Z]);
    }
    
    template<class T> inline Vector3D<T> operator/ (Vector3D<T> v, T s) {
        T inv = 1/s;
        return Vector3D<T>(inv*v[X], inv*v[Y], inv*v[Z]);
    }
    
    template<class T> inline T operator* (Vector3D<T> a, Vector3D<T> b) {
        return a[X]*b[X] + a[Y]*b[Y] + a[Z]*b[Z];
    }
    
    template<class T> inline Vector3D<T> operator^ (Vector3D<T> a, Vector3D<T> b) {
        return Vector3D<T>(a[Y]*b[Z] - a[Z]*b[Y],
                           a[Z]*b[X] - a[X]*b[Z],
                           a[X]*b[Y] - a[Y]*b[X]);
    }
    
    template<class T> inline bool operator== (Vector3D<T> a, Vector3D<T> b) {
        return a[X] == b[X] && a[Y] == b[Y] && a[Z] == b[Z];
    }
    
    template<class T> inline bool operator!= (Vector3D<T> a, Vector3D<T> b) {
        return a[X] != b[X] || a[Y] != b[Y] || a[Z] != b[Z];
    }
    
    //--(Funktionen)----------------------------------------------------------------
    
    template<class T> inline T* Vector3D<T>::array(void) const {
        return n;
    }
    
    template<class T> inline T Vector3D<T>::norm(void) const {
        return n[X]*n[X] + n[Y]*n[Y] + n[Z]*n[Z];
    }
    
    template<class T> inline T Vector3D<T>::length(void) const {
        return sqrt(norm());
    }
    
    #endif // VECTOR3D_CPP_
    


  • template<class T> inline Vector3D<T> operator+ (Vector3D<T> a, Vector3D<T> b) { 
        return Vector3D<T>(a[X]+b[X], a[Y]+b[Y], a[Z]+b[Z]); 
    }
    

    Es gibt kein globales X, Y, Z, also wird er es hier auch nicht finden 😕

    template<class T> inline Vector3D<T> operator+ (Vector3D<T> a, Vector3D<T> b) { 
        return Vector3D<T>(a[Vector3D<T>::X]+b[Vector3D<T>::X], a[Vector3D<T>::Y]+b[Vector3D<T>::Y], a[Vector3D<T>::Z]+b[Vector3D<T>::Z]); 
    }
    


  • template<class T> inline Vector3D<T> operator+ (Vector3D<T> a, Vector3D<T> b) {
        return Vector3D<T>(a[Vector3D<T>::X]+b[Vector3D<T>::X], a[Vector3D<T>::Y]+b[Vector3D<T>::Y], a[Vector3D<T>::Z]+b[Vector3D<T>::Z]);
    }
    

    Genau um diese Schreibweise wollte ich eigentlich auch drum herumkommen, denn dies wird bei manchen Funktionen ein riesiger Auffwand. Irgendwelche Ideen dazu?

    Eigentlich wollte ich mir hier nur eine Umschreibung von n[0]≡n[X],... einfallen lassen, welche für genau die beiden *.cpp Dateien gilt.



  • auch wenn's nicht besonders elegant ist, was spricht gegen

    #define X 0
    ...
    #undef X
    


  • Das war jetzt zum Schluss auch mein Gedanke :p
    Ich denke ich werde es so machen...



  • du kannst auch Vector3D von Point3D ableiten und das enum in Point3D protected deklarieren. dann erledigt sich das problem von selbst. außerdem könnte dann Vector3D etwa die vergleichsoperatoren erben. da sparst du auch noch programmieraufwand. für was gibts denn schließlich oop 😉



  • du kannst auch Vector3D von Point3D ableiten und das enum in Point3D protected deklarieren. dann erledigt sich das problem von selbst. außerdem könnte dann Vector3D etwa die vergleichsoperatoren erben. da sparst du auch noch programmieraufwand. für was gibts denn schließlich oop

    Durch die Ableitung existiert global, also außerhalb der Klassen, da wo eben die nicht-Member-Operatoren definiert werden, immernoch kein X, Y, oder Z.
    Außerdem hat das ganze dann mit OOP nicht mehr viel zu tun, denn ein Vektor ist kein Punkt!


Anmelden zum Antworten