我想存储数量,如重量,时间,长度。我认为这种方式更易读,避免了这样的函数不匹配:
Velocity computeSpeed(Distance d, Time t);
目前我只有
using float_type = double;
using Velocity = float_type;
using Distance = float_type;
using Time = float_type;
然而,对于我的应用程序,我需要一些转换,例如:
Distance toInches(Distance);
Distance toMillimeters(Distance);
我更希望有这样的东西:
Distance d;
std::cout << d.toInches();
但是,重载基类型可能有一些缺点:
- 它需要重载所有运算符或对浮点类型使用CRTP
- 这可能会影响效率
是否可以将“转换”常量方法添加到数值类型?附带问题:这种做法是不好还是矫枉过正?
注意:我用C++03卡住了:(
3条答案
按热度按时间lvjbypge1#
你的想法并不是全新的;这项建议是在2001年左右提出的。
你的设计的主要问题是
Distance toInches(Distance);
和Distance toMillimeters(Distance);
做的是完全相同的事情。您可以将它们都实现为Distance toFoo(Distance bar) { return bar };
原因是
1 inch
* 是 *2.54 mm
。它们实际上是相同的Distance
。你 * 可以 * 得到的是
float toInches(Distance d)
,明显的实现是float toInches(Distance d) { return d/Distanche::inch; }
,其中Distance::inch
是一个等于2.54 mm的常数。这些类型必须是类,因为您需要模板参数数学。你真的需要在SI中这样做,因为速度=距离/持续时间。只有SI单位才足够健全。
Unit<m1,kg1,s1>/Unit<m2,kg2,s2>=Unit<m1-m2,kg1-kg2,s1-s2>
,而Distance
只是Unit<1,0,0>
的typedef。dced5bon2#
我已经在C#中完成了你想做的事情,C#的重载能力比C少得多。结果是令人敬畏的,因为它保护您不受各种错误的影响,并保持代码简洁和中肯。(它消除了 * 偶然的复杂性 *。
它还允许IDE的完成建议功能发挥作用,因为它将向您展示您可以对每个变量执行哪些操作,而不必记住哪些全局范围函数适用于每个变量。
实现的方法是为每种不同类型的数量声明一个新类,该类包含一个以某种标准单位表示的值。(当然,您会为您的标准单位选择SI系统,对吗?)
一旦有了这些类,就可以重载所有适用的操作符,以便它们在每个类的示例之间以及在每个有意义的组合之间工作。
如果你喜欢冒险的生活,你甚至可以使用C的惊人能力来重载类型转换运算符,这样你就可以直接将
float
赋值给一个数量的示例,希望(祈祷)浮点数是正确的单位。我的建议是不要这样做,而是创建静态方法,如Length::ofMeters( float )
,Length::ofInches( float )
等。4ioopgfo3#
由于你的变量描述了某种物理属性,我建议你为每个变量创建一个类型,C++最强大的功能之一是你可以定义自己的类型(OOP),然后你将在后台使用基本类型,并为它们提供功能,如转换。
.toInches()
和重载运算符,例如我使用我自己的vector3d
类型,我重载了运算符 *,这样我就可以将它乘以一个矩阵,像这样vector3d operator*(const matrix3x3& mat)
还添加了unsigned int Length() const
这样的函数来获得向量的长度。