第二十篇:類操作符過載的相關規定與具體實現示例

穆晨發表於2017-01-26

前言

       有書這麼說過,C++設計的最大目的在於允許程式設計師定義自己的型別,並使它們用起來跟內建型別一樣容易和直觀。就目前看來,要實現這一點,最核心的莫過於操作符的過載。科學的過載可以讓類的使用最大程度地接近內建型別。本文將討論類操作符過載涉及到的一些原則和具體做法。

實現類操作符過載的兩種思路

       1. 友元函式法: 將待過載操作符視作非成員函式( 它宣告為運算元型別的友元函式 )

       應當採用這種機制過載的運算子有:IO操作符,算數操作符,關係操作符。

       2. 成員函式法: 將待過載操作符視作特殊的成員函式。

       應當採用這種機制過載的運算子有:賦值操作符,下標操作符,箭頭操作符,自增自減操作符。

       對於其他的操作符,兩種機制均可。至於為什麼這麼規定,請參閱相關C++教材,本文不詳述。

示例一:輸出操作符的過載( 友元函式法 )

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 /*
 7  * 定義一個簡單的書類
 8 */
 9 class Book {
10 public:
11     // 將輸出操作符函式設定為書類的友元函式
12     friend ostream & operator<< (ostream & out,const Book &b );
13     Book(string bookName, double price) {
14         this->bookName = bookName;
15         this->price = price;
16     }
17     string getName() const {
18         return bookName;
19     }
20     double getPrice() const {
21         return price;
22     }
23 private:
24     string bookName;
25     double price;
26 };
27     
28 /*
29  * 下為輸出操作符過載函式
30  * 物件設定為引用型別的目的僅僅是為了避免複製,故加上const宣告。
31 */
32 ostream &
33 operator<< (ostream & out, const Book &b) {
34     out << "書名: " << b.getName() << " 價格: " << b.getPrice();
35 
36     return out;
37 }
38 
39 int main()
40 {
41     Book book1("C++ Primer", 99.0);
42     Book book2("程式設計珠磯", 39.0);
43 
44     /*
45      * 像使用內建型別一樣使用物件
46     */
47     cout << book1 << endl;
48     cout << book2 << endl;
49 
50     return 0;
51 }

       執行結果:

       

小結1

       1. 輸出操作符的格式化操作應當儘量少

       2. 為什麼說IO操作符過載不能夠用成員函式法過載?請查閱C++相關教材。

示例二:賦值操作符的過載( 成員函式法 )

       接上例:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 /*
 7  * 定義一個簡單的書類
 8 */
 9 class Book {
10 public:
11     // 將輸出操作符函式設定為書類的友元函式
12     friend ostream & operator<< (ostream & out,const Book &b );
13     /*
14      * 下為輸出操作符過載函式
15       * 物件設定為引用型別的目的僅僅是為了避免複製,故加上const宣告。
16     */
17     Book & operator= (const Book &b) {
18         bookName = b.getName();
19         price = b.getPrice();
20 
21         return *this;
22     }
23     Book(string bookName, double price) {
24         this->bookName = bookName;
25         this->price = price;
26     }
27     string getName() const {
28         return bookName;
29     }
30     double getPrice() const {
31         return price;
32     }
33 private:
34     string bookName;
35     double price;
36 };
37     
38 /*
39  * 下為輸出操作符過載函式
40  * 物件設定為引用型別的目的僅僅是為了避免複製,故加上const宣告。
41 */
42 ostream &
43 operator << (ostream & out, const Book &b) {
44     out << "書名: " << b.getName() << " 價格: " << b.getPrice();
45 
46     return out;
47 }
48 
49 int main()
50 {
51     Book book1("C++ Primer", 99.0);
52     Book book2("程式設計珠磯", 39.0);
53 
54     /*
55      * 像使用內建型別一樣使用物件
56     */
57     cout << book1 << endl;
58     cout << book2 << endl;
59 
60     // 將book2賦值給book1後輸出
61     book1 = book2;
62     cout << book1 << endl;
63 
64     return 0;
65 }

執行結果

       

相關文章