2013-07-02 30 views
5

你会考虑这种设计不好的证据吗?比较不同类型的对象是否被认为是很好的设计?

//FooType and BarType not in the same hierarchy 
bool operator==(const FooType &, const BarType &); 
bool operator<(const FooType &, const BarType &); 

例如,如果FooTypedouble测量纪元以来的秒数和BarType是三个整数(年,月,日)在UTC提供的日期,像上面“意义”比较的元组。

你见过这种类型间比较吗?他们在C++社区中被压抑了吗?

+3

取决于谁将维护代码:)我倾向于将它实现为类方法,即BarType :: CompareToEpoch。顺便说一句,长整型会比秒以来测量秒数要好一倍... – Alex1985

+0

我认为这个被搁置的原因将是你的答案。 – ChiefTwoPencils

+0

我会说是的,因为'operator ==(const FooType&)'应该可能是'BarType'类的方法,而不是函数。 – chepner

回答

3

个人视野和经验

我个人并不在不同类型之间的比较皱眉。我甚至鼓励它,因为它可以提高代码的可读性;让你在做什么看起来更合乎逻辑。除了基本的数字类型,也可能是一个字符串和一个字符,我发现很难给出一个合乎逻辑的类型内比较,而且我不记得遇到过很多。我遇到了很多像这样使用的算术运算符。

如何使用它们

你应该小心你在做什么,他们很少使用的一个原因。如果您提供了两种不同类型的比较函数,则结果应该合乎逻辑,用户直观地预期了结果。也希望为它编写好的文档。 Mark Ransom已经说过了,但如果用户可以在两个方向上进行比较,那就很好。如果你认为你的比较不够清楚,你应该考虑使用命名函数。如果您的运营商可以有多种含义,这也是一个非常好的解决方案。

可能出现的错误

您不必在什么用户将与你所写的内容做的完全控制。 Tletnes举了一个很好的例子,比较两个整数,但结果没有意义。与此相反,两种不同类型的比较可能是非常正确的。浮点数和整数都代表秒,可以很好地比较。

算术运算符

下一步逻辑,我想显示与算术运算符帧内类型的例子。算术运算符在讨论类型内用法时很像逻辑运算符。

假设你有一个运算符+一个二维向量和一个正方形。这是做什么的?用户可能认为它会缩放广场,但另一个用户确信它会翻译!这些问题可能会让用户感到非常沮丧。你可以通过提供很好的文档来解决这个问题,但是我个人更喜欢的是专门命名的函数,比如Translate。

结论

内型逻辑运算符可以是有益的,使干净的代码,但坏的使用使得一切都只是更加复杂。

+1

在“可能出错”一节中需要注意的一点是,不同类型支持的比较次数可能导致所需功能的数量支持这些操作,从而迅速崩溃。 2种类型,4种功能(a == a,a == b,b == a,b == b)。 3种类型,9种功能。这是N^2复杂性(假设反思性和对称性)。 – Suedocode

1

好的设计会指出你应该只比较兼容含义的值。一般类型是一个很好的线索来的意思,但不是最后一个字,其实在很多情况下,两个相同类型的值可能有不兼容的含义,如followng两个整数:

int seconds = 3 //seconds 
int length = 2; //square inches 
if(seconds >= length){ 
    //what does this mean? 
} 

在这个例子中,我们比较长度和秒数,但是两者之间没有任何关系。

int test_duration = 3 //minutes 
float elapsed_time = 2.5; //seconds 
if((test_duration * 60) >= elapsed_time){ 
    //tes is done 
} 

在这个examaple我们比较不同类型(单位)的两个值但是它们的含义仍然兼容(它们都表示时间),所以(假设就是为什么两个人那种方式存储的一个很好的理由(如易于使用的API等)这是一个很好的设计

4

首先,使用免费功能,而不是成员函数没有错,实际上这是推荐的做法。请参阅Scott Meyer的How Non-Member Functions Improve Encapsulation。尽管提供了两个方向的比较:

bool operator==(const FooType &, const BarType &); 
bool operator==(const BarType &, const FooType &); 

其次,如果比较有意义,则提供这些比较是完全可以接受的。例如,标准库允许您将std::complex值与浮点数进行比较,但不能小于。

你想要避免的一件事是没有意义的比较。在您的示例中,其中一个时间值是双精度值,这意​​味着一旦您考虑标准升级,就会对任何浮点或整数值进行比较。这可能比你想要的要多,因为没有办法确定任何特定的值是否代表一个时间。类型检查的丢失意味着存在潜在的意外错误。

相关问题