5

在 C++ 中重载“==”运算符时,是否有关于明确表示相等性的标准定义,或者有一组关于“==”应该如何表现的准则?

我目前有一个类不会将其整个自身存储在内存中。它基本上使用优先级队列来确定其内部对象被使用的频率,以及何时从队列末尾弹出对象,它们会从内存中删除并写入磁盘。

所以现在问题出现在相等上,这两个对象相等意味着什么。因为我们可以从在各个方面都相同的对象 A 和 B 开始,所以它们将相同的数据加载到内存中,并且它们在磁盘上具有相同的数据。但是在 A 和 B 上调用了一系列函数之后,它们现在可能会有所不同。A 和 B 在磁盘上仍然有相同的数据,但它们将不同的数据加载到内存中。所以问题是应该A == B解析为真还是假?

是否有一套规则或指南来定义这应该如何工作?或者这只是我决定什么对程序最有意义并记录“==”做什么的情况?

4

3 回答 3

16

任何operator==重载都应该尊重等价关系的公理,即

  • x == x, 对于所有对象x
  • 如果x == y, 那么y == x
  • 如果x == yy == z, 那么x == z.

许多使用的算法==依赖于它实现等价关系,在 §17.6.3.1 中正式化为EqualityComparable概念。

于 2012-12-20T22:37:13.717 回答
11

标准中没有关于重载operator ==应该如何表现的定义。

但是一个足够好的指导方针是 - 如果你必须考虑它,只要你有,你可能甚至不应该超载operator ==。如果它不直观,则弊大于利。

所以问题是 A == B 应该解析为真还是假?

IMO,它应该导致编译器错误。:)

于 2012-12-20T22:36:10.003 回答
2

ALL 运算符重载应该做“你所期望的”。如果对象实质上不相同,那么让运算符 == 返回 true 是没有意义的。您如何定义“相同”当然是我们可以争论的问题。可以实现一个“nocasestring”,它的行为就像一个字符串,但是如果你有一个字符串“HELLO”和一个“hello”,它们被认为是相等的,因为大小写无关紧要。或者,如果您实现了自己的“Float”类,其中 == 会进行一些数学运算以避免常规浮点的脆弱比较。所以是的,在某些情况下 == 并不完全“因为所有元素都是 a. == b.”,但它确实应该是例外。

同样,如果一个运算符不完全有意义,不要让它做一些“令人惊讶”的事情(例如-对于字符串 - 它有什么作用?或者将一个字符串乘以另一个字符串 - 乘以整数可能有意义)。

编程中的惊喜是个坏主意。如果事情没有按照您的预期进行,那么您会从阅读/修改代码中获得糟糕的体验。

于 2012-12-20T22:49:20.300 回答