# 分析模式-计量的C++实现——回复ch0877

ch0877翻译了一篇名叫《分析模式-计量》的文章（http://www.csdn.net/Develop/article/14/14449.shtm），很不错。我就试着用C++实现了一下。

#ifndef _QUANTITY_H_
#define _QUANTITY_H_

#include <crtdbg.h>

template<typename ValueType>
class Quantity
{
public:
template<typename UnitType>Weight(const ValueType & amount, const UnitType & unit)
: m_amount(amount), m_unit(new unit_wrap<UnitType, ValueType>(unit))
{
}
~Quantity()
{
delete m_unit;
}
Quantity(const Quantity & other)
: m_amount(other.m_amount), m_unit(other.m_unit ? other.m_unit->clone() : 0)
{
}
Quantity & operator=(const Quantity & rhs)
{
if(&rhs == this)
return *this;
m_amount = rhs.m_amount;
delete m_unit;
m_unit = rhs.m_unit ? rhs.m_unit->clone() : 0;
return *this;
}
template<typename UnitType> void convert(const UnitType & new_unit)
{
_ASSERT(m_unit);
m_amount = m_unit->to_standard(m_amount);
delete m_unit;
m_unit = new unit_wrap<UnitType, double>(new_unit);
m_amount = m_unit->from_standard(m_amount);
}
Quantity & operator+=(const Quantity & rhs)
{
_ASSERT(m_unit);
_ASSERT(rhs.m_unit);
m_amount = m_unit->from_standard(
m_unit->to_standard(m_amount) + rhs.m_unit->to_standard(rhs.m_amount) );
return *this;
}
Quantity & operator-=(const Quantity & rhs)
{
_ASSERT(m_unit);
_ASSERT(rhs.m_unit);
m_amount = m_unit->from_standard(
m_unit->to_standard(m_amount) - rhs.m_unit->to_standard(rhs.m_amount) );
return *this;
}
bool operator==(const Quantity & rhs)
{
_ASSERT(m_unit);
_ASSERT(rhs.m_unit);
return equal(m_unit->to_standard(m_amount) , rhs.m_unit->to_standard(rhs.m_amount) );
}
bool operator>(const Quantity & rhs)
{
_ASSERT(m_unit);
_ASSERT(rhs.m_unit);
return (m_unit->to_standard(m_amount) > rhs.m_unit->to_standard(rhs.m_amount) );
}

private:
template<typename T>bool equal(const T & l, const T & r)
{return (l == r);}
template<>bool equal<double>(const double & l, const double & r)
{
static double precision = 0.000000001;
return (l - r < precision);
}

private:
template<typename ValueType>
class unit_base
{
public:
virtual ~unit_base()
{
}
public:
virtual unit_base * clone() const = 0;
virtual ValueType to_standard(const ValueType & val) const = 0;
virtual ValueType from_standard(const ValueType & val) const = 0;
};
template<typename UnitType, typename ValueType>
class unit_wrap : public unit_base<ValueType>
{
public:
unit_wrap(const UnitType & unit) : m_content(unit)
{
}
public:
virtual unit_base<ValueType> * clone() const
{
return new unit_wrap(m_content);
}
virtual ValueType to_standard(const ValueType & val) const
{
return m_content.to_standard(val);
}
virtual ValueType from_standard(const ValueType & val) const
{
return m_content.from_standard(val);
}
private:
UnitType m_content;
};

private:
ValueType    m_amount;
unit_base<ValueType> * m_unit;
};

template<typename ValueType>
Quantity<ValueType> inline _cdecl operator+(const Quantity<ValueType> & a,
const Quantity<ValueType> & b)
{return (Quantity<ValueType>(a)+=b);}

template<typename ValueType>
Quantity<ValueType> inline _cdecl operator-(const Quantity<ValueType> & a, const Quantity<ValueType> & b)
{return (Quantity<ValueType>(a)-=b);}

#endif /* _QUANTITY_H_ */

typedef Quantity<double> Weight;
class UNIT_KG
{
public:
double to_standard(double val) const
{return val;}
double from_standard(double val) const
{return val;}
};

class UNIT_G
{
public:
double to_standard(double val) const
{return val/1000.0;}
double from_standard(double val) const
{return val*1000.0;}
};

UNIT_KG _kg;
UNIT_G _g;

Weight w1(1.0, _kg);
Weight w2(1.0, _g);
w1.convert(_g);
w1.convert(_kg);
w2 = w1;
Weight w10(1.0, _kg);
Weight w20(500.0, _g);
w10 +=  w20;
Weight w30(w10 + w20);
bool b = (w10 == w20);
b = (w30 > w10);

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
07-16
12-07 49
12-06 436
12-06 101
12-07 822
12-11 20
12-11 136
12-09 462
12-11 159
12-06 280
12-05 98
12-05 70
12-11 16
12-07 56

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

noho

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。