Überladen von Operatoren



  • Gutentag,

    ich beschäftige mich zurzeit mit den Operatoren einer Klasse und wie man die überladen kann. Ich praktiziere es an dem Beispiel eines Vector2.

    Die Klasse schaut bis jetzt so aus:

    namespace Private
    {
    	template<typename T>
    	class Vector2
    	{
    	private:
    	protected:
    	public:
    		T x;
    		T y;
    
    		Vector2(T pX, T pY);
    		Vector2(const Vector2<T>& copy);
    		Vector2<T>& operator=(const Vector2<T>& copy);
    
    		Vector2<T> operator-() const;
    
    		Vector2<T>& operator-=(const Vector2<T>& right);
    		Vector2<T> operator-(const Vector2<T>& right);
    		Vector2<T>& operator+=(const Vector2<T>& right);
    		Vector2<T> operator+(const Vector2<T>& right);
    		Vector2<T>& operator*=(const Vector2<T>& right);
    		Vector2<T> operator*(const Vector2<T>& right);
    		Vector2<T>& operator/=(const Vector2<T>& right);
    		Vector2<T> operator/(const Vector2<T>& right);
    
    		bool operator==(const Vector2<T>& right);
    		bool operator!=(const Vector2<T>& right);
    
    		Vector2<T>& operator-=(const T& right);
    		Vector2<T> operator-(const T& right);
    		Vector2<T>& operator+=(const T& right);
    		Vector2<T> operator+(const T& right);
    		Vector2<T>& operator*=(const T& right);
    		Vector2<T> operator*(const T& right);
    		Vector2<T>& operator/=(const T& right);
    		Vector2<T> operator/(const T& right);
    	};
    
    	template<typename T>
    	inline Vector2<T>::Vector2(T pX, T pY) : x(pX), y(pY) {}
    
    	template<typename T>
    	inline Vector2<T>::Vector2(const Vector2<T>& copy) : x(copy.x), y(copy.y) {}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator=(const Vector2<T>& copy)
    	{
    		x = copy.x;
    		y = copy.y;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator-() const
    	{
    		return Vector2<T>(-x, -y);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator-=(const Vector2<T>& right)
    	{
    		x -= right.x;
    		y -= right.y;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator-(const Vector2<T>& right)
    	{
    		return Vector2<T>(x - right.x, y - right.y);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator+=(const Vector2<T>& right)
    	{
    		x += right.x;
    		y += right.y;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator+(const Vector2<T>& right)
    	{
    		return Vector2<T>(x + right.x, y + right.y);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator*=(const Vector2<T>& right)
    	{
    		x *= right.x;
    		y *= right.y;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator*(const Vector2<T>& right)
    	{
    		return Vector2<T>(x * right.x, y * right.y);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator/=(const Vector2<T>& right)
    	{
    		x /= right.x;
    		y /= right.y;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator/(const Vector2<T>& right)
    	{
    		return Vector2<T>(x / right.x, y / right.y);
    	}
    
    	template<typename T>
    	inline bool Vector2<T>::operator==(const Vector2<T>& right)
    	{
    		return x == right.x ? y == right.y : false;
    	}
    
    	template<typename T>
    	inline bool Vector2<T>::operator!=(const Vector2<T>& right)
    	{
    		return !(*this == right);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator-=(const T& right)
    	{
    		x -= right;
    		y -= right;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator-(const T& right)
    	{
    		return Vector2<T>(x - right, y - right);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator+=(const T& right)
    	{
    		x += right;
    		y += right;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator+(const T& right)
    	{
    		return Vector2<T>(x + right, y + right);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator*=(const T& right)
    	{
    		x *= right;
    		y *= right;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator*(const T& right)
    	{
    		return Vector2<T>(x * right, y * right);
    	}
    
    	template<typename T>
    	inline Vector2<T>& Vector2<T>::operator/=(const T& right)
    	{
    		x /= right;
    		y /= right;
    		return *this;
    	}
    
    	template<typename T>
    	inline Vector2<T> Vector2<T>::operator/(const T& right)
    	{
    		return Vector2<T>(x / right, y / right);
    	}
    }
    
    typedef Private::Vector2<int> Vector2I;
    

    Damit kann ich erstmal die Vektoren miteinander addieren, substrahieren, multiplizieren, etc...

    indem ich folgendes schreibe:

    Vector2I v1(1, 1);
    	Vector2I v2(2, 2);
    	Vector2I v3(3, 3);
    
    	v1 = -v2;
    	v1 = v1 - v2;
    	v1 = v2 - v3;
    

    was mir aber noch fehlt bzw. wollte ich fragen ob es überhaupt möglich ist auch solche operationen durchzuführen/zu überladen:

    v1 - v2; // Hier wird dann v1 als Referenz geändert zurückgegeben
    v1 + v2; // etc...
    

    Gruß


  • Mod

    Ja, das geht. Du darfst deine Operatoren definieren wie du möchtest. Aber es ist stark davon abzuraten, die übliche Semantik zu verändern. Was du beschreibst ist doch, was man üblicherweise += nennen würde, nicht + .


  • Mod

    return x == right.x ? y == right.y : false;
    

    merkwürdige Art, && zu schreiben. 🙂


Anmelden zum Antworten