C 運算子過載的注意事項

2021-07-05 02:49:07 字數 3277 閱讀 2248

1、過載操作符沒必要一定是成員函式,還可以是友元函式。

2、過載操作符函式為成員函式主要是你需要操作類內部的成員,

必須是成員函式或友元函式才行。

3、至於由深淺拷貝的原因要使其成為成員函式,這個不知道。

4、如果運算子被過載為全域性函式,那麼只有乙個引數的運算子叫做一元運算子,有兩個引數的運算子叫做二元運算子。

如果運算子被過載為類的成員函式,那麼一元運算子沒有引數,二元運算子只有乙個右側引數,因為物件自己成了左側引數。

從語法上講,運算子既可以定義為全域性函式,也可以定義為成員函式。文獻[murray , p44-p47]對此問題作了較多的闡述,並總結了表8-4-1的規則。

運算子規則

所有的一元運算子

建議過載為成員函式

= ()  ->

只能過載為成員函式

+= -= /= *= &= |= ~= %= >>= <<=

建議過載為成員函式

所有其它運算子

建議過載為全域性函式

第四點來自  

簡單地說,c++標準規定要這樣使用,但為什麼要這樣規定,請看下面:

1:對於賦值操作符(=)--比較特別,因為任何類如果不提供顯示的拷貝賦值(即過載=),則編譯器會隱式地提供乙個。這樣的話,如果你再通過友元宣告,進行全域性的定義會造成呼叫二義性(即使允許,編譯也會出錯)。

2:對於所有樓主提到的操作符(=,,(),->),只能宣告為成員函式是為了避免不合法的書寫通過編譯(這是推測出的原因,更深層的可能要研究 c++ 的設計了)。這涉及到 c++ 中型別的隱式轉換。下面通過**例子說明:

c/c++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#include

classx

x(int){}// int 型別可以被隱式轉換成 x

friendbooloperator<(constx& x1,constx& x2)// 只是測試,無意義

};

classy

y(int){}// int 型別可以被隱式轉換成 y

booloperator<(consty& y)const// 只是測試,無意義

};

intmain()

y y;

if(1 < y)// 不合法,使用成員過載函式,函式的第乙個引數是 const *this,1 不能被隱式轉換

{}

return0;

}

// 注:編譯的時候可以通過注釋掉不同的**來檢視錯誤(即合法性),後面解釋不能作為友元全域性過載的原因

由上面的**可以知道,如果將 =,,(),-> 進行友元全域性過載,那麼就會出現 1=x; 1[x]; 1->x; 1(x); 這樣的合法語句(起碼編譯器認為這些是合法的)--參考**中的 if(1

c/c++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#include

classx

x(int){}// int 型別可以被隱式轉換成 x

friendconstx& operator+=(constx& x1,constx& x2)// 只是測試,無意義

};

intmain()

運算子過載的注意事項

在 c 中進行運算子過載時的注意事項 c 規定,運算子過載不改變運算子的優先順序。以下運算子不能被過載 sizeof 過載運算子 賦值運算子 和型別強制轉換運算子 時,只能將它們過載為成員函式,不能過載為全域性函式。必要時需要過載賦值運算子 即進行深拷貝,以避免兩個物件內部的指標指向同一片儲存空間。...

C 中的運算子過載概念與注意事項

所謂運算子過載,就是讓運算子有特殊的含義。傳統的運算子包括但不限於以下幾種 1算術運算子 2邏輯運算子 3關係運算子 4賦值運算子 注意沒有 5位運算子 6雜項運算子 包括取位址符號 解引用符號 三目運算子?sizeof 取變數大小操作符 運算子過載的本質,也是一種函式,區別是這種函式定義時候需要使...

過載運算子的形式和注意事項

運算子過載 函式過載 是c 多型的重要實現手段之一。通過運算子過載對運算子功能進行特殊定製,使其支援特定型別物件的運算,執行特定的功能,增強c 的擴充套件功能。1 不可臆造運算子。2 運算子原有運算元的個數 優先順序和結合性不能改變。3 運算元中至少乙個是自定義型別。4 保持過載運算子的自然含義。一...