我的运算符在我的派生类中重载函数的继承存在问题。
#pragma once
#include "Math.hpp"
using namespace Math;
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
float &operator[](const char &) const;
Euler &operator=(const Euler &);
Euler &operator+=(const Euler &);
Euler &operator-=(const Euler &);
Euler &operator*=(const float &);
Euler &operator/=(const float &);
Euler operator+(const Euler &) const;
Euler operator-(const Euler &) const;
Euler operator*(const float &) const;
Euler operator/(const float &) const;
bool operator==(const Euler &) const;
bool operator!=(const Euler &) const;
bool IsValid() const;
void Clear();
};
inline Euler::Euler()
{
x = y = z = 0.f;
}
inline Euler::Euler(const float &_x, const float &_y, const float &_z)
{
x = _x;
y = _y;
z = _z;
}
inline float &Euler::operator[](const char &c) const
{
return ((float *)this)[c];
}
inline Euler &Euler::operator=(const Euler &e)
{
x = e.x;
y = e.y;
z = e.z;
return *this;
}
inline Euler &Euler::operator+=(const Euler &e)
{
x += e.x;
y += e.y;
z += e.z;
return *this;
}
inline Euler &Euler::operator-=(const Euler &e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return *this;
}
inline Euler &Euler::operator*=(const float &e)
{
x *= e;
y *= e;
z *= e;
return *this;
}
inline Euler &Euler::operator/=(const float &e)
{
x /= e + M_FLT_EPSILON;
y /= e + M_FLT_EPSILON;
z /= e + M_FLT_EPSILON;
return *this;
}
inline Euler Euler::operator+(const Euler &e) const
{
return Euler(x + e.x, y + e.y, z + e.z);
}
inline Euler Euler::operator-(const Euler &e) const
{
return Euler(x - e.x, y - e.y, z - e.z);
}
inline Euler Euler::operator*(const float &f) const
{
return Euler(x * f, y * f, z * f);
}
inline Euler Euler::operator/(const float &f) const
{
return Euler(x / (f + M_FLT_EPSILON), y / (f + M_FLT_EPSILON), z / (f + M_FLT_EPSILON));
}
inline bool Euler::operator==(const Euler &e) const
{
return e.x == x && e.y == y && e.z == z;
}
inline bool Euler::operator!=(const Euler &e) const
{
return e.x != x || e.y != y || e.z != z;
}
inline bool Euler::IsValid() const
{
using namespace std;
return isfinite(x) && isfinite(y) && isfinite(z);
}
inline void Euler::Clear()
{
x = y = z = 0.f;
}
class Vector : public Euler
{
public:
using Euler::Euler;
void Rotate(const Angle &);
void Rotate2D(const float &);
float Length() const;
float LengthSqr() const;
float Length2D() const;
float Length2DSqr() const;
float DistTo(const Vector &) const;
float DistToSqr(const Vector &) const;
};
inline float Vector::Length() const
{
return Sqrt((x * x) + (y * y) + (z * z));
}
inline float Vector::LengthSqr() const
{
return (x * x) + (y * y) + (z * z);
}
inline float Vector::Length2D() const
{
return Sqrt((x * x) + (y * y));
}
inline float Vector::Length2DSqr() const
{
return (x * x) + (y * y);
}
inline float Vector::DistTo(const Vector &v) const
{
return (*this - v).Length();
}
inline float Vector::DistToSqr(const Vector &v) const
{
return (*this - v).LengthSqr();
}
下面显示的代码包含distto和DistToSqr函数中的错误,其中它计算(* this - v)为超类Euler,因此找不到长度函数。
我想知道为什么会这样,因为这段代码会在我的笔记本电脑而不是我的桌面上编译。
如果有人能告诉我为什么这段代码不起作用以及修复它的最佳方法,我将不胜感激。
看起来这样做是一种合理的解决方法。
inline float Vector::DistTo(const Vector &v) const
{
Vector tmp = (*this - v);
return tmp.Length();
}
仍然想知道这是否是修复它的最佳选择。
答案 0 :(得分:1)
我将假设Euler
可能总是被用作更具体类型的基类型?如果是这样,您可以使用CRTP模式解决此问题。以下是此样式的代码子集:
#include <cmath>
template <typename Derived>
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
template <typename T>
Derived & operator-=(Euler<T> const &);
template <typename T>
Derived operator-(Euler<T> const &) const;
private:
Derived & derived() const {
return static_cast<Derived &>(*this);
}
Derived const & derived() {
return static_cast<Derived const &>(*this);
}
};
template <typename Derived>
Euler<Derived>::Euler() : x(0), y(0), z(0)
{}
template <typename Derived>
Euler<Derived>::Euler(const float &_x, const float &_y, const float &_z)
: x(_x), y(_y), z(_z)
{}
template <typename Derived>
template <typename T>
Derived & Euler<Derived>::operator-=(Euler<T> const & e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return derived();
}
template <typename Derived>
template <typename T>
Derived Euler<Derived>::operator-(Euler<T> const & e) const
{
return Derived(x - e.x, y - e.y, z - e.z);
}
class Vector : public Euler<Vector>
{
public:
using Euler<Vector>::Euler;
float Length() const;
float DistTo(const Vector &) const;
};
inline float Vector::Length() const
{
return std::sqrt(x * x + y * y + z * z);
}
inline float Vector::DistTo(const Vector & v) const
{
return (*this - v).Length();
}