1. 程式人生 > 實用技巧 >第30課 操作符過載的概念

第30課 操作符過載的概念

函式過載能夠擴充套件系統中已經存在的函式功能那麼過載是否可以擴充套件其他更多功能

1. 複數類需要解決的問題

——下面的複數解決方案是否可行?

不可行+操作符只提供對C++ 基本資料型別的運算,不支援類(複數)的相加運算

      

+操作符能不能作用類之間--------不能

 1 #include<stdio.h> 
 2                
 3 //複數解決方案  物件可以進行加法操作嗎  不足之處:應該講成員影藏
 4 class Complex
 5 {
 6 public: 
 7     int a;        //實部
8 int b; //虛部 9 }; 10 11 //全域性函式 引數為複數物件 12 Complex add(const Complex& p1, const Complex& p2) 13 { 14 Complex ret; //定義返回值型別 15 16 ret.a = p1.a + p2.a; 17 ret.b = p1.b + p2.b; 18 19 return ret; 20 } 21 22 int main() 23 { 24 Complex c1 = { 1,2 }; 25 Complex c2 = { 3
,4 }; 26 // Complex c3 = c1 + c2; // 物件之間不可以進行加法操作 27 Complex c3 = add(c1,c2); //加法操作換成函式呼叫 28 29 printf("c3.a=%d,c3.b=%d\n", c3.a, c3.b); //4,6 30 31 return 0; 32 }

第一個解決方案

 1 #include<stdio.h> 
 2 
 3 //複數解決方案  物件可以進行加法操作嗎
 4 class Complex
 5 {
 6     int
a; //實部 7 int b; //虛部 8 public: 9 Complex(int a = 0, int b = 0) //建構函式將實部虛部隱藏 10 { 11 this->a = a; 12 this->b = b; 13 } 14 15 int getA() //功能函式 16 { 17 return a; 18 } 19 int getB() //功能函式 20 21 { 22 return b; 23 } 24 25 friend Complex add(const Complex& p1, const Complex& p2); //add函式作為友元函式 26 27 }; 28 29 //全域性函式---------引數為複數物件----不能直接訪問類的成員,所以使用友元 30 Complex add(const Complex& p1, const Complex& p2) 31 { 32 Complex ret; //定義返回值型別 33 34 ret.a = p1.a + p2.a; //呼叫有緣函式解決可以呼叫類的成員 35 ret.b = p1.b + p2.b; 36 37 return ret; 38 } 39 40 int main() 41 { 42 //使用建構函式進行初始化 43 Complex c1 (1,2 ); 44 Complex c2 (3,4 ); 45 Complex c3 = add(c1, c2); //c1+c2比較完美 46 47 printf("c3.a=%d,c3.b=%d\n", c3.getA(), c3.getB()); 48 49 return 0; 50 }

思考:Add 函式可以解決Complex 物件相加的問題,但是 Comples 是現實世界中確實存在的複數,並且複數在數學中的地位和普通的實數相同。

c可以支援整形浮點的+操作符運算,對於複數加法,由於複數類是我們自己定義實現的,那麼可不可以自定義+操作符

為什麼不讓 + 操作符也支援複數相加呢?

2.操作符過載

(1)C++中的過載能夠擴充套件操作符的功能

(2)操作符的過載函式的方式進行,

(3)本質:

      是用特殊形式函式擴充套件操作符的功能

(3)通過operator關鍵字可以定義特殊函式operator本質通過函式過載操作符

(4)語法:TypeoperatorSign(const Type p1, const Type p2)

                {

                   Type ret;

                   return ret;

                } 

       Sign為系統中預定義操作符,+-*、/,

 1 #include<stdio.h> 
 2 
 3 //複數解決方案  讓+操作支援繼續複數
 4 /*
 5   operator 關鍵字  定義特殊函式  聽過函式過載操作符
 6 */
 7 
 8 
 9 class Complex
10 {
11     int a;        //實部
12     int b;        //虛部
13 public:
14     Complex(int a = 0, int b = 0)  
15     {
16         this->a = a;
17         this->b = b;
18     }
19 
20     int getA()        
21     {
22         return a;
23     }
24     int getB()      
25 
26     {
27         return b;
28     }
29 
30     //方式一:通過全域性普通的函式實現複數相加
31     friend Complex Add(const Complex& p1, const Complex& p2);
32 
33 
34     //方式二:通過全域性函式過載“+”操作符實現複數相加
35     friend Complex operator + (const Complex& p1, const Complex& p2);
36 
37 };
38 
39 //全域性普通函式
40 Complex Add(const Complex& p1, const Complex& p2)
41 {
42     Complex ret;
43 
44     ret.a = p1.a + p2.a;
45     ret.b = p1.b + p2.b;
46 
47     return ret;
48 }
49 
50 //Complex add(const Complex& p1, const Complex& p2)    
51 
52 //add全部換為operator +
53 
54 //全域性過載操作符+
55 Complex operator + (const Complex& p1, const Complex& p2)
56 {
57     Complex ret;    
58 
59     ret.a = p1.a + p2.a;    
60     ret.b = p1.b + p2.b;
61 
62     return ret;
63 }
64 
65 int main()
66 {
67 
68     Complex c1(1, 2);
69     Complex c2(3, 4);
70 
71     //方式一的呼叫
72     //Complex c3 = Add(c1, c2);  //方式一呼叫。缺點是無法寫成:c1 + c2的形式;
73 
74     //方式二的呼叫 
75     //Complex c3 = operator+(c1, c2);//把“opertor+”當成函式名一樣的呼叫
76 
77     Complex c3 = c1 + c2;            //更直觀,本質上是呼叫“operator+”這個函式
78 
79     printf("c3.a=%d,c3.b=%d\n", c3.getA(), c3.getB());
80 
81     return 0;
82 }

3.可將操作符過載函式定義為類的成員函式

(1)比全域性操作符過載函式少一個引數左運算元this引數充當)------借用成員函式隱含this指標

(2)不需要依賴友元可以完成操作符過載

(3)編譯器優先成員函式尋找操作符過載函式

 1 #include<stdio.h>       //不依賴友元完成操作符過載    儘量不使用友元  用類的成員函式擴充套件
 2 
 3 class Complex
 4 {
 5     int a;       
 6     int b;       
 7 public:
 8     Complex(int a = 0, int b = 0)   
 9     {
10         this->a = a;
11         this->b = b;
12     }
13 
14     int getA()                 
15     {
16         return a;
17     }
18     int getB()             
19 
20     {
21         return b;
22     }
23 
24     //優先呼叫成員函式版本  
25     Complex operator + (const Complex& p)    //操作符過載函式
26     {
27         Complex ret;       
28         printf("Complex operator + (const Complex& p) \n");
29 
30         ret.a = this->a + p.a;     //左運算元this+ 右運算元 
31         ret.b = this->b + p.b;
32 
33         return ret;
34     }
35 
36     friend Complex  operator +(const Complex& p1, const Complex& p2);      //add函式作為友元函式  
37 
38 };
39 
40 //全域性函式過載版本
41 Complex operator + (const Complex& p1, const Complex& p2)
42 {
43     Complex ret;         //定義返回值型別 
44     printf("Complex operator + (const Complex& p1, const Complex& p2)\n");
45 
46     ret.a = p1.a + p2.a;       
47     ret.b = p1.b + p2.b;
48 
49     return ret; 
50 }
51 
52 
53 
54 int main()
55 {
56 
57     //使用建構函式進行初始化
58     Complex c1(1, 2);
59     Complex c2(3, 4);        
60     Complex c3 = c1.operator + (c2);   //    Complex c3 = operator + (c1, c2);
61     Complex c3 = c1 + c2;          //優先選擇成員函式,而不是全域性的operator+    
62 
63 
64     printf("c3.a=%d,c3.b=%d\n", c3.getA(), c3.getB()); 
65 
66     return 0;
67 }

4.小結

(1)操作符過載C++強大特性之一其本質是通過函式擴充套件操作符的功能

(2)operator關鍵字是實現操作符過載關鍵

(3)操作符過載遵循相同的函式過載規則

(4)全域性函式成員函式都可以實現對操作符的過載,但編譯器優先選擇通過成員函式實現的操作符過載函式