Skip to content

Instantly share code, notes, and snippets.

@ryutorion
Created April 13, 2014 15:01
Show Gist options
  • Save ryutorion/10587642 to your computer and use it in GitHub Desktop.
Save ryutorion/10587642 to your computer and use it in GitHub Desktop.
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
using namespace std;
class angle;
class radian;
// angle(度数法)とradian(弧度法)の実装がほぼ同じなため
// 共通処理をまとめる
template <typename T>
class angle_base {
protected:
explicit angle_base(float v)
: mValue(v)
{}
explicit angle_base(angle_base const & v)
: mValue(v.value())
{}
public:
float value() const
{
return mValue;
}
T & operator+=(T const & rhs)
{
mValue += rhs.value();
return *static_cast<T *>(this);
}
T & operator-=(T const & rhs)
{
mValue -= rhs.value();
return *static_cast<T *>(this);
}
T & operator*=(float rhs)
{
mValue *= rhs;
return *static_cast<T *>(this);
}
private:
float mValue;
};
class angle : public angle_base<angle> {
public:
explicit angle(float v = 0.f)
: angle_base<angle>(v)
{}
explicit angle(radian const & rad);
};
class radian : public angle_base<radian> {
public:
explicit radian(float v = 0.f)
: angle_base<radian>(v)
{}
explicit radian(angle const & ang);
};
// 両方のクラスがangle_baseを継承していることがわからないと
// value()が利用できないので,実装を分離
angle::angle(radian const & rad)
: angle_base<angle>(rad.value() / M_PI * 180.f)
{}
radian::radian(angle const & ang)
: angle_base<radian>(ang.value() / 180.f * M_PI)
{}
int main(int argc, char ** argv)
{
angle a(90.f);
angle b(45.f);
angle c;
radian r;
c += a;
// compile error
// r = a;
r = radian(a);
cout << a.value() << endl;
cout << b.value() << endl;
cout << c.value() << endl;
cout << r.value() << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment