与帝国单位合作

Roe*_*oel 2 c++ units-of-measurement

我正在玩一个应用程序,粗略地说,这是一种建筑行业的建模应用程序.将来我希望用户可以同时使用SI单位和英制单位.根据我的理解,美国建筑行业习惯于在指定测量时使用几分之一英寸,例如3 1/2英寸 - 而在SI中我们写3.5,而不是3 1/2.我正在寻找一种方法在我的软件中使用这些不同的系统 - 存储它们,对它们进行计算等,不仅解析用户输入的内容.它应该能够以他输入的方式向用户显示测量值,同时能够用其他测量 - 例如增加3厘米到1 1/2英寸.因此,如果用户绘制5英尺长的墙和3米的另一个墙,则应在用户选择的默认单位系统中显示总测量值.

我还没有确定应该为用户输入数据添加多少灵活性; 例如,如果他进入1英尺14英寸,那么下次显示测量值时应该是2英尺2英寸吗?然而,在我决定这样的事情之前,我正在寻找一种以精确的形式存储测量值的方法,这就是我的问题所在.

我正在使用C++,我看过Boost.Units,但这似乎没有提供处理分数的方法.

简单的选择是将所有内容转换为毫米,但舍入错误将导致无法返回到用户输入的精确测量值(如果他在英制测量中输入).所以我需要更复杂的东西.

现在我正在使用一个暂定名为"距离"的类,看起来在概念上如下:

class Distance
{
public:
    Distance(double value);
    // operators +, -, *, /
    Distance operator+(const Distance& that);
    ...etc...

    std::string StringForm(); // Returns a textual form of the value

    Distance operator=(double value);

private:
    <question: what should go here?>
}
Run Code Online (Sandbox Code Playgroud)

这清楚地表明了我的问题所在.最明显的事情是有一个枚举,说明这个距离是存储SI还是英制单位,并且有字段(可能是双倍)存储米,厘米和毫米(如果它是以SI为单位,英尺和英寸)这是帝国的.然而,这将使该类的实现乱丢if(SI)else ...,并且在内存中非常浪费.另外,我必须为脚和英寸存储分子和分母,以便能够精确地存储1/3",例如.

因此,根据我的设计要求,我正在寻找关于如何解决这些问题的一般设计建议.当然,如果有一个已经完成这些事情的C++库,或者我可以看到另一种语言的库来复制概念,那就太好了.

LBu*_*kin 5

我肯定会考虑在距离类中添加一个Units属性.然后,您可以重载+, - ,*,/(和相关)运算符,以便只有当单位是相同类型时,才能对距离进行算术运算.

就个人而言,我会将所有测量值标准化为您将在每个系统中支持的最低测量单位(例如,SI为毫米,英制为英寸),但也存储用户输入的表示.以标准化形式执行所有计算,但在向用户呈现时转换回更易读的形式.

您还应该考虑创建Distance immutable的实例 - 并在执行算术运算时创建新的Distance.

最后,您可以创建辅助方法以在不同单位之间进行转换 - 甚至可能在对具有不同单位的距离执行算术时在内部调用这些方法.只需将所有内容转换为通用单位,然后执行计算.

就个人而言,我不会在每个系统中为测量创建多种类型的路径 - 我认为您最好合并逻辑并允许您的系统以多态方式处理测量.


Mat*_*lls 5

企业应用程序架构模式中查看 Martin Fowler 的Money模式- 它直接适用于这种情况。推荐阅读。Fowler 还在他的网站上发布了一篇关于Quantity模式的简短文章,这是更通用的 Money 版本。