10

根據對this線程的回覆,operator=不能作爲非成員函數重載。舉例來說,下面讓編譯器非常生氣:Overloading operator = as非會員

class MyClass 
{ 
    // ... 
}; 

MyClass& operator=(MyClass& Left, MyClass& Right) 
{ 
    // ... 
} 

這是爲什麼?我有一個容器類與getter和setter,所以一個成員函數是不必要的,它會打破封裝。上述線程的答案之一表示,它要確保「L值作爲其第一個操作數」,但我不完全明白這意味着什麼。有人可以澄清嗎?

此外,有operator=operator()operator[]operator-> 「古怪」 的情況下......?或者,我應該執行所有重載操作符作爲成員函數...? (我知道這是完全合法的做法,但我正在尋找更好的做法。)

+1

也看到這個線程http://stackoverflow.com/questions/3938036/rationale-of-enforcing-some-operators-to-be-members – UmmaGumma 2011-03-21 16:45:49

+0

我認爲getter/setter方法破壞封裝超過賦值運算符。注意:如果你沒有定義一個你的類已經有一個賦值操作符。嘗試一下。 – 2011-03-21 16:50:57

+0

成員函數不會破壞封裝;他們是它的一部分。偏好打造「非成員,非友元函數」可能會導致更簡單的類,但在一般情況下,暴露一切必要措施,落實運營商=()更可能削弱封裝不是讓運營商=()的成員。 – 2011-03-21 16:54:14

回答

6

如果您的類沒有賦值運算符(作爲成員),則編譯器會默認生成一個,就像它會生成一個拷貝構造函數,如果你沒有提供。

因此,如果您稍後嘗試定義非成員賦值操作符,它將會「生氣」。那會有兩個!

+0

規則可以簡單地改變,試圖找到一個非成員第一個。 – GManNickG 2011-03-21 16:40:26

+0

@GMan如果非會員運營商在另一個翻譯單位? ODR違規? – 2011-03-21 16:42:00

+0

@Bo:聽起來很合理。 – GManNickG 2011-03-21 16:45:03

1

這是爲什麼?

除非你宣佈一個,編譯器聲明在類的operator=與簽名operator= (C&, C&)operator= (C&, const C&)

如果您被允許重載分配,大多數使用將是不明確的。

然後你可能會遊說附加規則要麼:

  • 假裝沒有宣佈operator=如果用戶宣佈一個是可見的,因爲如果非會員operator=隱藏成員編譯operator=
  • 使您的用戶在重載期間聲明更好的匹配。

這兩種選擇都會使已經非常複雜的規則複雜化,只爲operator=增加一個特殊情況。

很少有人想去那裏。

而且還有您尚未公開此功能的合法用途。

或者,任何合理使用的。

只有顯示一些合理的用例時,C++規則纔會變得更加複雜。