允许继承类使用相同的功能

时间:2019-05-07 22:20:34

标签: c++

我有一个由EulerAngle类继承的Vector类。我希望能够在EulerAngle对象上使用Vector类中的运算符,而不必重写EulerAngle类中的运算符,并尽可能将Vector3更改为Angle。我该怎么办?

class Vector3 {
public:  
    float x, y, z;

    // ctors...
    __forceinline Vector3() : x{}, y{}, z{} {

    __forceinline Vector3( float x, float y, float z ) : x{ x }, y{ y }, z{ z } {

    }

    // functions...

    // operators...
    __forceinline Vector3 &operator +=( const Vector3 &other ) {
        x += other.x;
        y += other.y;
        z += other.z;

        return *this;
    }

    __forceinline Vector3 &operator +=( float scalar ) {
        x += scalar;
        y += scalar;
        z += scalar;

        return *this;
    }

    __forceinline Vector3 operator +( float scalar ) const {
       return Vector3( x + scalar, y + scalar, z + scalar );
    }

    __forceinline Vector3 operator +( const Vector3 &other ) const {
       return Vector3( x * other.x, y * other.y, z * other.z );
    }

}

class EulerAngle : public Vector3 {
private:

};

// example, MSVC says this is an error and that there is no suitable conversion from EulerAngle to Vector3
EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f

在回答了几个问题之后,我添加了以下代码以使其工作。但是我仍然想知道是否有更好的方法来实现这一目标?

class EulerAngle : public Vector3 {
public:
    using Vector3::Vector3;

    __forceinline EulerAngle( const Vector3 &other ) : Vector3( other ) {

    }
};

2 个答案:

答案 0 :(得分:2)

Vector3不继承自Vector3时,您可以使用template<typename T> operator T() const { static_assert(std::is_base_of<Vector3, T>::value, "T is not inherited from Vector3"); return T{x,y,z}; } 中的user-defined conversion到想要的类型,并带有静态断言。

C++20

LIVE DEMO

================================================ ================

ADDON

通过template<typename T> requires std::DerivedFrom<T,Vector3> constexpr operator T() const { return T{x,y,z}; } concepts的引入,可以将以上代码重写为:

 // error.h
 struct ErrorInfo {};

 template <class T>
 const ErrorInfo& error(const T&);

 // Found.h
 struct Found
 {
  const char *begin, *end;
 };

 Found find(const char*,const char*);

 struct Found_ErrorInfo : ErrorInfo
 {
  const char *type;
  char fault[3];
  unsigned index;

  Found_ErrorInfo()
   : type("Not found"), fault{'\e','w',0}, index(0) {};

  ~Found_ErrorInfo() { delete this; }
 };

 template <>
 const ErrorInfo& error<Found>(const Found &f)
 {
  return *new Found_ErrorInfo();
 }

 // main.cpp
 int main()
 {
  Found f = find("dada", "I love my mama");

  if(f.begin != nullptr) std::cout << f.begin;
  else const ErrorInfo &info = error(f);
 }

LIVE DEMO

答案 1 :(得分:0)

Vector3类中的using构造函数从Vector3EulerAngle添加隐式构造函数

class EulerAngle : public Vector3 {
    using Vector3::Vector3;
    EulerAngle(const Vector3& from) : Vector3(from) {}
}

如果您要这样做

EulerAngle ang = { 1.f, 1.f, 1.f };
ang += 5.f;
EulerAngle ang2 = ang + 5.f;
EulerAngle ang3 = Vector3{ 2.f, 2.f, 2.f } + ang2;