This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
一度作ってから,実装がほぼ同じなのでCRTPでまとめてみたものの,二項演算子の実装があんまりすっきりしなくて,いったん放置.
しかし,何故こういう安全策が用意されないのかなぁ,と考えていて,そもそもこういう角度を扱うような状況って処理速度が云々って言っていることが多いし,const参照で渡したら間接参照になるから多少は速度が落ちるかも,とか考えているのではないかと.