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类对象与常数的乘法运算结果无误。以后的两篇博客依次讲述动态内存分配与类继承内容,有错误的地方欢迎指正。

相关文章
相关标签/搜索