C++;尺度分析(Barnes和Nackman) 我最近读了C++源代码中的一系列文章,“暂停反映:五个五的列表”。在中,Scott Meyers讨论了Barton和Nackman对单元问题的解决方案。作为一名航空航天行业的嵌入式软件工程师,这是一个特别的惊喜!这一刻让我很兴奋。到目前为止,我还没有听说过这种方法(这些作者也没有)
我已经做了研究,试图找到更多关于解决方案的信息。我在这里看到了这个演示: 我想我了解我读到的关于这个解决方案的所有内容。但我觉得好像少了一块拼图。这一美丽、优雅的解决方案在任何地方都无法解决规模问题。我特别感兴趣的转换不仅仅是一个乘法因子。例如,温度在开尔文、摄氏度和华氏度之间转换。我希望能够互换使用这些温度 我的问题是:C++;尺度分析(Barnes和Nackman) 我最近读了C++源代码中的一系列文章,“暂停反映:五个五的列表”。在中,Scott Meyers讨论了Barton和Nackman对单元问题的解决方案。作为一名航空航天行业的嵌入式软件工程师,这是一个特别的惊喜!这一刻让我很兴奋。到目前为止,我还没有听说过这种方法(这些作者也没有),c++,design-patterns,C++,Design Patterns,我已经做了研究,试图找到更多关于解决方案的信息。我在这里看到了这个演示: 我想我了解我读到的关于这个解决方案的所有内容。但我觉得好像少了一块拼图。这一美丽、优雅的解决方案在任何地方都无法解决规模问题。我特别感兴趣的转换不仅仅是一个乘法因子。例如,温度在开尔文、摄氏度和华氏度之间转换。我希望能够互换使用这些温度 我的问题是: 我错过什么了吗?是否在我忽略的单元解决方案讨论中讨论了比例 如果没有,我如何进一步处理这个问题?是否有一种现有模式可以与B&N方法结合使用来完成解决方案 我的目标是能够在不进
typedef Units<double, miles> uMiles;
typedef Units<double, kilometers> uKilometers;
uMiles d1 (1.0);
uKilometers d2 (1.60934);
d1 += d2;
if (d1.val(miles) == 2.0) // PASS
if (d1.val(kilometers) == 3.21869) // PASS
typedef-Units-uMiles;
类型定义单位uKilometers;
uMiles d1(1.0);
uKilometers d2(1.60934);
d1+=d2;
如果(d1.val(miles)==2.0)//通过
如果(d1.val(公里)=3.21869)//通过
注:
我看到了增压装置解决问题的方法,我不喜欢它。对我来说,这很难理解。通常,我也不允许使用boost之类的外部库
备份数据:
单元类别如下所述:
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
class Units
{
public:
// ------------------------------------------------------
explicit
Units (T initVal = 0)
: val (initVal)
{
}
// --------------------------------------------------------------------
// Operator: Assignment from type T
Units<T, m, l, t, q, k, i, a>&
operator= (const T rhs)
{
val = rhs;
return *this;
}
// --------------------------------------------------------------------
// Operator: Type Converstion to T
operator T () const
{
return val;
}
// --------------------------------------------------------------------
// Operator: +=
Units<T, m, l, t, q, k, i, a>&
operator+= (const Units<T, m, l, t, q, k, i, a>& rhs)
{
val += rhs.val;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator-= (const Units<T, m, l, t, q, k, i, a>& rhs)
{
val -= rhs.val;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator*= (T rhs)
{
val *= rhs;
return *this;
}
// --------------------------------------------------------------------
Units<T, m, l, t, q, k, i, a>&
operator/= (T rhs)
{
val /= rhs;
return *this;
}
// --------------------------------------------------------------------
// Get Reference
T&
Val ()
{
return val;
}
// --------------------------------------------------------------------
// Get Value
const T&
Val () const
{
return val;
}
private:
T val;
};
// ----------------------------------------------------------------------------
// Operator: Addition
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator+ (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result += rhs;
}
// ----------------------------------------------------------------------------
// Operator: Subtraction
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator- (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result -= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Multiplication
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator* (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result *= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Division
template<class T, int m, int d, int t, int q, int k, int i, int a>
const Units<T, m, d, t, q, k, i, a>
operator/ (const Units<T, m, d, t, q, k, i, a> & lhs,
const Units<T, m, d, t, q, k, i, a> & rhs)
{
Units<T, m, d, t, q, k, i, a> result (lhs);
return result /= rhs;
}
// ----------------------------------------------------------------------------
// Operator: Multiplication (Creates New Type)
template<class T,
int m1, int d1, int t1, int q1, int k1, int i1, int a1,
int m2, int d2, int t2, int q2, int k2, int i2, int a2>
// Return Type
Units<T, m1 + m2, d1 + d2, t1 + t2, q1 + q2, k1 + k2, i1 + i2, a1 + a2>
operator* (const Units<T, m1, d1, t1, q1, k1, i1, a1>& lhs,
const Units<T, m2, d2, t2, q2, k2, i2, a2>& rhs)
{
// New Return type
typedef Units<T,
m1 + m2,
d1 + d2,
t1 + t2,
q1 + q2,
k1 + k2,
i1 + i2,
a1 + a2> ResultType;
return ResultType (lhs.Val() * rhs.Val());
}
// ----------------------------------------------------------------------------
// Operator: Division (Creates New Type)
template<class T,
int m1, int d1, int t1, int q1, int k1, int i1, int a1,
int m2, int d2, int t2, int q2, int k2, int i2, int a2>
// Return Type
Units<T, m1 - m2, d1 - d2, t1 - t2, q1 - q2, k1 - k2, i1 - i2, a1 - a2>
operator/ (const Units<T, m1, d1, t1, q1, k1, i1, a1>& lhs,
const Units<T, m2, d2, t2, q2, k2, i2, a2>& rhs)
{
// New Return type
typedef Units<
T,
m1 - m2,
d1 - d2,
t1 - t2,
q1 - q2,
k1 - k2,
i1 - i2,
a1 - a2> ResultType;
return ResultType (lhs.Val() / rhs.Val());
}
模板//角度
班级单位
{
公众:
// ------------------------------------------------------
明确的
单位(T初始值=0)
:val(initVal)
{
}
// --------------------------------------------------------------------
//运算符:T类型的赋值
单位&
运算符=(常数T rhs)
{
val=rhs;
归还*这个;
}
// --------------------------------------------------------------------
//操作员:键入对话到T
运算符T()常量
{
返回val;
}
// --------------------------------------------------------------------
//接线员:+=
单位&
运算符+=(常量单位和rhs)
{
val+=rhs.val;
归还*这个;
}
// --------------------------------------------------------------------
单位&
运算符-=(常量单位和rhs)
{
val-=rhs.val;
归还*这个;
}
// --------------------------------------------------------------------
单位&
运算符*=(T rhs)
{
val*=rhs;
归还*这个;
}
// --------------------------------------------------------------------
单位&
运算符/=(T rhs)
{
val/=rhs;
归还*这个;
}
// --------------------------------------------------------------------
//获取参考
T&
Val()
{
返回val;
}
// --------------------------------------------------------------------
//获得价值
常数&
Val()常数
{
返回val;
}
私人:
T值;
};
// ----------------------------------------------------------------------------
//接线员:加法
模板
常量单位
操作员+(常量单位和左侧,
施工单位和rhs)
{
单位结果(lhs);
返回结果+=rhs;
}
// ----------------------------------------------------------------------------
//操作员:减法
模板
常量单位
操作员-(常量单位和左侧,
施工单位和rhs)
{
单位结果(lhs);
返回结果-=rhs;
}
// ----------------------------------------------------------------------------
//运算符:乘法
模板
常量单位
操作员*(施工单位和左侧),
施工单位和rhs)
{
单位结果(lhs);
返回结果*=rhs;
}
// ----------------------------------------------------------------------------
//接线员:分区
模板
常量单位
操作员/(常量单位和左侧),
施工单位和rhs)
{
单位结果(lhs);
返回结果/=rhs;
}
// ----------------------------------------------------------------------------
//运算符:乘法(创建新类型)
模板
//返回类型
单位
操作员*(施工单位和左侧),
施工单位和rhs)
{
//新的返回类型
typedef单位ResultType;
返回结果类型(lhs.Val()*rhs.Val());
}
// ----------------------------------------------------------------------------
//操作员:除法(创建新类型)
模板
//返回类型
单位
操作员/(常量单位和左侧),
施工单位和rhs)
{
//新的返回类型
类型定义单位<
T
m1-m2,,
d1-d2,
t1-t2,
第一季度至第二季度,
k1-k2,
i1-i2,
a1-a2>结果类型;
返回结果类型(lhs.Val()/rhs.Val());
}
此类允许我们编写如下代码:
// Base Types
typedef Units<double, 1,0,0,0,0,0,0> uMass;
typedef Units<double, 0,1,0,0,0,0,0> uLength;
typedef Units<double, 0,0,1,0,0,0,0> uTime;
typedef Units<double, 0,0,0,1,0,0,0> uCharge;
typedef Units<double, 0,0,0,0,1,0,0> uTemperature;
typedef Units<double, 0,0,0,0,0,1,0> uIntensity;
typedef Units<double, 0,0,0,0,0,0,1> uAngle;
// Derived Types
typedef Units<double, 0,2, 0,0,0,0,0> uArea;
typedef Units<double, 0,3, 0,0,0,0,0> uVolume;
typedef Units<double, 0,1,-1,0,0,0,0> uVelocity;
typedef Units<double, 0,1,-2,0,0,0,0> uAcceleration;
typedef Units<double, 1,1,-2,0,0,0,0> uForce;
uMass mass;
uTime time;
uForce force;
uLength length;
uVelocity velocity;
uAcceleration acceleration;
// This will compile
mass = 7.2;
acceleration = 3.5;
force = mass * acceleration;
// These will not compile ** Enforcing Dimensional Unit Correctness
force = 7.2 * acceleration;
force = mass;
force *= acceleration;
//基类型
类型定义单位uMass;
类型定义单位长度;
typedef单位uTime;
类型DEF单位uCharge;
类型DEF装置温度;
强度;
typedef单位uAngle;
//派生类型
类型定义单位uArea;
紫外线体积单位;
紫外线度;
类型定义单位加速;
typedef单位uForce;
麻省大学质量;
使用时间;
力量
Units<double,0,0,0,0,0,0,0> K2C(243.15);
Units<double,0,0,0,0,1,0,0> uCelsius;
Units<double,0,0,0,0,1,0,0> uKelvin;
uCelsius = uKelvin - K2C;
typdef enum {
CELSIUS,
KELVIN,
FAHRENHEIT
} temp_t;
void Units::convertTemp(const temp_t from, const temp_t to) {
switch(from) {
case KELVIN:
val -= 243.15;
case CELSIUS:
if(to == FAHRENHEIT)
//conversion
else if(to == KELVIN)
val += 243.15;
break;
case FAHRENHEIT:
// convert to celsius
if(to == KELVIN)
//convert to Kelvin
}
}
1.6 * 7 kilometers per hour = 11.2 kilometers per hour
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
class SIUnits
{
// ...
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
class ImperialUnits
{
// ...
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
ImperialUnits<T, m, l, t, q, k, i, a>
convert(SIUnits<T, m, l, t, q, k, i, a> value)
{
T conversionFactor = 1.0;
for (int x = 0; x < m; ++x)
{
// This is some function that maps from one to the other.
conversionFactor *= siMassToImperialMassFactor;
conversionFactor += siMassToImperialMassOffset;
}
for (int x = m; x < 0; ++x)
{
// This is some function that maps from one to the other.
conversionFactor *= siMassToImperialMassFactor;
conversionFactor += siMassToImperialMassOffset;
}
// Do the same for other dimensions as well...
class Celsius;
class Kelvin;
class Fahrenheit
{
// ...
Fahrenheit(Celsius t); // Auto-convert from celsius
Fahrenheit(Kelvin t); // Auto-convert from Kelvin
// ...
template<class T, // Precision
int SystemOfUnits, // Denotes the system of units used, SI or Imperial.
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a> // Angle
class Units
{
// etc.
template<class T, // Precision
int m, // Mass
int l, // Length
int t, // Time
int q, // Charge
int k, // Temperature
int i, // Luminous Intensity
int a, // Angle
class M, // Mass unit type
class L, // Length unit type
class T, // Time unit type
class Q, // Charge unit type
class K, // Temperature unit type
class I, // Luminous Intensity unit type
class A> // Angle unit type
class Units
{
// etc.