2011-01-12 53 views
3

我現在回顧舊的C++代碼庫,看到了很多代碼會是這樣的:應該通過C++中的「operator ==」實現「operator!=」嗎?

bool SomeClass::operator==(const SomeClass& other) const 
{ 
    return member1 == other.member1 && member2 == other.member2; 
} 

bool SomeClass::operator!=(const SomeClass& other) const 
{ 
    return member1 != other.member1 || member2 != other.member2; 
} 

顯然比較邏輯被複制和上面的代碼將有可能在兩個地方,而不是在一個改變。

AFAIK實施operator!=的典型方式是這樣的:

bool SomeClass::operator!=(const SomeClass& other) const 
{ 
    return !(*this == other); 
} 

在任何邏輯變化發生在operator==它會自動地反映在operator!=因爲它只是調用operator==並執行否定後者的情況。

是否有任何合理的情況下,operator!=應該以任何其他方式實現,除了在C++代碼中重用operator==

+2

同樣,應該嘗試以最不重複的方式實現`>,> =,<=,<`運算符。 – 2011-01-12 10:14:52

+0

規則不應該是絕對的。所有規則一般都適用。但我確信總會有特定的情況下,他們不會。但是提出一個問題(除非你昨天碰巧這樣做)一般是不可能的(因爲它們是規則的例外)。它的要求都是天鵝白。是的,所有天鵝都是白色的(直到1500年在澳大利亞發現黑天鵝)。 Ceaser:「rara avis in terris nigroque simillima cygno」 – 2011-01-12 16:59:14

回答

9

在大多數情況下,a!=b的語義應該等於!(a==b)

這同樣適用於所有其他運營商真正:a<b應該等於!(a=>b)!(a==b || a>b)a<=b && !(a==b)等等等等。

爲此,boost.operators提供了一些很棒的工具來自動生成其他函數的運算符。


然而,當你給一些特定的語義操作員(即:你不使用==檢查兩個項目是否是相同的,但像STL與>><<確實做一些花哨的東西),你可能想給他們不同的實現。

這種做法,一般來說,並不建議,即使STL和許多助推庫都這樣做。


編輯 - 有點另外:

什麼,我說,截至目前僅涉​​及經營者的語義。如果您認爲您的a!=b的語義應該是!(a==b)你有兩種方法來實現:通過調用其它運營商,也就是如果你使用boost.operators會發生什麼


  • bool operator!=(a,b) { return !(a==b); }

  • 從頭開始實施它們。

第一種方法通常更容易實施和更安全。可以證明第二種選擇的最常見的事情是優化,儘管它可能不值得:現代編譯器在大多數情況下不會增加任何開銷(如果你看boost.operators源代碼,你會看到很多關於它們的評論依賴NRVO添加任何開銷,或者如果編譯器不提供NRVO,它們的代碼如何改變)。因爲重要的是語義(即:你的操作員的行爲方式,他們爲任何可能的輸入返回的內容)。無論你選擇什麼選項,無論如何,它應該對你的應用程序邏輯沒有什麼不同。

4

恕我直言,它是合理和強大的實施!=在==。 (或相反方向)

+0

-1對於錯誤的建議..你怎麼用`!=`來實現`==`? – Nawaz 2011-01-12 10:18:21

+4

@Nawaz:`a == b iff!(a!= b)`。這是根據定義。 – 2011-01-12 10:26:16

2

語義上是(意思是==應該是!=的邏輯互補),但實際上(編碼)你不必這樣做。

3

是否有任何合理的情況,其中operator!=應該以任何其他方式實現,除了在C++代碼中重用operator==

我不這麼認爲。但是對於其他代碼也是如此,例如後綴++應該始終可以在前綴++方面實現的(當然除了原生類型,其中優化器可以生成更高效的代碼,但我相信即使這樣的說法成立)和operator +應該幾乎總是可以在以下方面實現operator +=(當你使用代理對象來延遲執行時是個例外)。

這就是爲什麼std::relops存在。