//全域性
friend complex operator+(
const complex &c1,
const complex &c2)
;//成員,記得加=號,「+=」
complex &
operator+=
(const complex &c)
;
先來看b = a + 1.1
;,實際上會被轉換為b = operator+(a, 1.1);
這樣的形式進行呼叫;因為存在轉換建構函式,並且第乙個引數為 double,那麼編譯器就會將 1.1 轉換為乙個匿名 complex 物件complex(1.1),進而在運算子過載函式內部將它們兩個的實部,虛部相加,然後返回乙個匿名 complex 物件並賦值給 b;
而對於b = 2.2 + a
;,也是一樣的道理,被轉換為b = operator+(2.2, a)
;這樣的形式,然後又呼叫轉換建構函式將 2.2 轉換為乙個匿名 complex 物件complex(2.2),後面的步驟同上;
對於b = a + 1.1
;,被轉換為b = a.operator+(1.1)
;,1.1 也是被轉換為complex(1.1);
對於b = 2.2 + a
;,被轉換為b = (2.2).operator+(a)
;,這很顯然是不正確
的,進而編譯報錯;
理由:
以全域性函式的形式過載 +,是為了保證 + 運算子的運算元能夠被對稱的處理
;換句話說,小數(double)在 + 左邊和右邊都是正確的;
理由:
我們首先要明白,運算子過載的初衷是給類新增新的功能,方便類的運算,它作為類的成員函式是理所應當的,是首選的;不過,類的成員函式不能對稱地處理資料,程式設計師必須在(參與運算的)所有型別的內部都過載當前的運算子;
以上面的情況為例,我們必須在 complex 和 double 內部都過載 + 運算子,這樣做不但會增加運算子過載的數目,還要在許多地方修改**,這顯然不是我們所希望的,所以 c++ 進行了折中,允許以全域性函式(友元函式)的形式過載運算子;
採用全域性函式能使我們定義這樣的運算子,它們的引數具有邏輯的對稱性;
與此相對應的,把運算子定義為成員函式能夠保證在呼叫時對第乙個(最左的)運算物件不出現型別轉換,也就是上面提到的「c++ 不會對呼叫成員函式的物件進行型別轉換」;
有一部分運算子過載既可以是成員函式也可以是全域性函式,雖然沒有乙個必然的、不可抗拒的理由選擇成員函式,但我們應該優先考慮成員函式,這樣更符合運算子過載的初衷;
另外有一部分運算子過載必須是全域性函式,這樣能保證引數的對稱性;除了 c++ 規定的幾個特定的運算子外,暫時還沒有發現必須以成員函式的形式過載的運算子
;c++ 規定,箭頭運算子->
、下標運算子、函式呼叫運算子
()
、賦值運算子=
只能以成員函式的形式過載;
全域性函式和成員函式
class test1 public test1 this,int a,int b 全域性函式形式 test1 int a 0,int b 0 this a a this b b public int a int b public 成員函式 test1 t add test1 t2 test1 t3...
全域性函式VS成員函式
1 include 2 3using namespace std 45 class test613 intgeta 1417 intgetb 1821 22 test add test t2 2328 void print 2933 protected 34 private 35 inta,b 36...
c 成員函式和全域性函式的區分
include using namespace std 設計乙個立方體的類,求出立方體的面積和體積 分別用全域性函式和成員函式進行判斷兩個立方體是否相同 class cube 獲取長 intget l 設定寬 void set w int w 獲取寬 intget w 設定高 void set h ...