C++基礎——運算符重載友元函數示例

1、前言ios

  其實本人學習C++的目的,只是爲了體會OOP設計思想,併爲利用System Verilog驗證複雜設計作準備。若是想要真正作點軟件方面項目級的東西,還須要掌握其餘高級語言和庫、框架等知識。所以該系列博文僅注重語言基礎和設計思想。上一篇該系列博文講述了C++中基本的類封裝,此次利用運算符重載友元函數來體會下C++的靈活性。框架

2、運算符重載友元函數ide

  本文一樣以《C++ Primer Plus》中的一個簡單示例來說解此內容。場景以下:時間粗劣地分爲時和分兩部分。須要完成兩個時間的相加、時間與倍數的相乘(這個操做不太恰當,湊活看吧)以及顯示時間操做。先上代碼:函數

類聲明:學習

 1 #ifndef MYTIME_H_  2 #define MYTIME_H_
 3 
 4 using std::ostream;  5 
 6 class Time  7 {  8 private:  9     int hours; 10     int minutes; 11 public: 12  Time(); 13     Time(int h,int m=0); 14     void Reset(int h = 0,int m = 0); 15     Time operator+(const Time& t) const; 16     Time operator*(double mult) const;//成員函數
17 
18     friend Time operator*(double m,const Time& t) //友元函數(inline)
19         {return t * m;} 20     friend ostream& operator<<(ostream & os,const Time& t);//<<左側必須是ostream對象 返回ostream&
21 }; 22 #endif
mytime.h

類方法定義:spa

 1 #include <iostream>
 2 #include "mytime.h"
 3 
 4 Time::Time()  5 {  6     hours = minutes = 0;  7 }  8 
 9 Time::Time(int h,int m) 10 { 11     hours = h; 12     minutes = m; 13 } 14 
15 void Time::Reset(int h,int m) 16 { 17     hours = h; 18     minutes = m; 19 } 20 
21 Time Time::operator+(const Time& t) const
22 { 23  Time sum; 24     sum.minutes = minutes + t.minutes; 25     sum.hours = hours +t.hours +sum.minutes / 60; 26     sum.minutes %= 60; 27     return sum; 28 } 29 
30 Time Time::operator*(double mult) const
31 { 32  Time result; 33     long totalminutes = hours * mult * 60 + minutes * mult; 34     result.hours = totalminutes / 60; 35     result.minutes = totalminutes % 60; 36     return result; 37 } 38 
39 ostream& operator<<(ostream& os,const Time& t) 40 { 41     os << t.hours << " hours, " << t.minutes << " minutes"; 42     return os; 43 }
mytime.cpp

  以上代碼的設計原則是:想讓Time類對象的相加、與常數相乘以及打印操做與C++內置類型一致。所以+、*、<<三個符號必須進行運算符重載操做,即對此類對象使用這三個運算符時的具體實現細節需從新定義。聲明格式爲:<返回值類型> operator<op>()。可是這裏存在一個問題,成員函數Time operator*(double mult) 在被調用時,類對象必須放置在*符號左側,也就是說當表達式爲m*t(t爲Time類對象)時,編譯器會報錯。使用<<運算符打印Time類對象時一樣會遇到此問題。設計

  爲了實現用戶友好,使用沒有此限制的友元函數重載運算符是個不錯的選擇。友元函數是類接口的擴展,這類函數雖然不是類成員函數,但能夠訪問類私有成員。須要注意的一點是:<<輸出數據時,左側必須是ostream類對象。所以重載<<運算符時,必須使函數返回參數中ostream類對象自己才能正確編譯cout << A << B;語句。這條語句與(cout << A) << B;等同。code

3、應用程序及結果分析對象

應用程序示例代碼:blog

 1 #include <iostream>
 2 #include "mytime.h"
 3 
 4 using std::endl;  5 
 6 int main()  7 {  8     using std::cout;  9 
10  Time planning; 11     Time coding(2,40); 12     Time fixing(5,55); 13  Time total; 14  Time adjusted1,adjusted2; 15 
16     cout << "planning time = "; 17     cout << planning << endl; 18 
19     cout << "coding time = "; 20     cout << coding << endl; 21     cout << "fixing time = "; 22     cout << fixing << endl; 23     cout << endl; 24 
25     total = coding + fixing; 26     cout << "coding + fixing = "; 27     cout << total << endl; 28 
29     adjusted1 = total * 1.5;//調用成員函數
30     cout << "total * 1.5 = "; 31     cout << adjusted1 << endl; 32 
33     adjusted2 = 1.5 * total;//調用友元函數
34     cout << "1.5 * total = "; 35     cout << adjusted2 << endl; 36 
37 }
usetime.cpp

  Time類對象planning建立時隱式調用用戶定義默認構造函數,而coding和fixing因有參數傳遞調用第二個構造函數,這正是C++的多態性質。能夠看到,打印Time類對象與打印C++內置類型對象無異。重點關注「*」運算符的使用,adjusted1和adjusted2表達式中乘法運算依次調用了成員函數和友元函數。C++編譯器一樣會自動識別用戶的意圖。打印結果如圖:

  應用程序運行正確,重載的兩個Time類對象的加法運算和Time類對象與常數的乘法運算結果無誤。以後的兩篇博客依次講述動態內存分配與類繼承內容,有錯誤的地方歡迎指正。

相關文章
相關標籤/搜索