C++ primer plus 第11章 使用類
1.新增加法運算子
operator+()函式的名稱使得可以使用函式表示法或運算子表示法來呼叫它。
total=coding.operator+(fixing);//函式表示法
total=coding+fixing;//運算子表示法
多數C++運算子都可以用這樣的方式過載。過載的運算子不必是成員函式,但必須至少有一個運算元是使用者定義的型別。
過載運算子的限制:(1)過載後的運算子必須至少有一個運算元是使用者定義的型別,這將防止使用者為標準型別過載運算子。因此,不能將減法運算子(-)過載為計算兩個double值的和,而不是它們的差。(2)使用運算子時不能違反運算子原來的句法規則。不能修改運算子的優先順序(3)不能建立新運算子(4)不能過載部分運算子(見書387面)。
2.友元
C++控制對類物件私有部分的訪問。通常,公有類方法提供唯一的訪問途徑,但有時候這種限制太嚴格,以至於不適合特定的程式設計問題。在這種情況下,C++提供了另外一種形式的訪問許可權:友元——友元函式、友元類和友元成員函式。
通過讓函式成為類的友元,可以賦予該函式與類的成員函式相同的訪問許可權。在為類過載二元運算子時(帶兩個引數的運算子)常常需要友元。
A=B*2.75;//可以被裝換成下面的成員函式呼叫:
A=B.operator*(2.75);
A=2.75*B;//這個語句又將如何轉換?
A=operator*(2.75,B)//A=2.75*B;可以與此非成員函式呼叫匹配
對於非成員函式過載運算子函式來說,運算子表示式左邊的運算元對應於運算子函式的第一個引數,運算子表示式右邊的運算元對應於運算子函式的第二個引數。非成員函式不能直接訪問類的私有資料,至少常規非成員函式不能訪問。然而,有一種特殊的非成員函式可以訪問類的私有成員——友元函式。
建立友元函式的第一步是將其原型放在類宣告中,並在原型宣告前加上關鍵字friend:
friend Time operator*(double m,const Time &t);
雖然operator*()函式是在類宣告中宣告的,但它不是成員函式,因此不能使用成員運算子來呼叫;雖然operator*()函式不是成員函式,但是它與成員函式的訪問許可權相同。
第二步是編寫函式定義。因為它不是成員函式,所以不要使用Time::限定符。另外不要在定義中使用關鍵字friend。
常用的友元:過載<<運算子
void operator<<(ostream & os,const Time &t) { os<<t.hours<<"hours,"<<t.minutes<<"minutes"; } //這樣就可以使用,trip是Time的一個物件 //cout<<trip
//mytime.h
#ifndef MYTIME3_H_
#define MYTIME3_H_
#include<iostream>
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h,int m=0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h=0,int m=0);
Time operator+(const Time &t)const;
Time operator-(const Time &t) const;
Time operator*(double n) const;
friend Time operator*(double m,const Time &t)
{return t*m;}
friend std::ostream & operator<<(std::ostream &os,const Time &t);
};
#endif
//mytime.cpp
#include "mytime.h"
Time::Time()
{
hours=minutes=0;
}
Time::Time(int h,int m)
{
hours=h;
minutes=m;
}
void Time::AddMin(int m)
{
minutes+=m;
hours+=minutes/60;
minutes%=60;
}
void Time::AddHr(int h)
{
hours+=h;
}
void Time::Reset(int h,int m)
{
hours=h;
minutes=m;
}
Time Time::operator+(const Time & t)const
{
Time sum;
sum.minutes=minutes+t.minutes;
sum.hours=hours+t.hours+sum.minutes/60;
sum.minutes%=60;
return sum;
}
Time Time::operator-(const Time &t)const
{
Time diff;
int tot1,tot2;
tot1=t.minutes+60*t.hours;
tot2=minutes+60*hours;
diff.minutes=(tot2-tot1)%60;
diff.hours=(tot2-tot1)/60;
return diff;
}
Time Time::operator*(double mult)const
{
Time result;
long totalminutes=hours*mult*60+minutes*mult;
result.hours=totalminutes/60;
result.minutes=totalminutes%60;
return result;
}
std::ostream & operator<<(std::ostream &os,const Time &t)
{
os<<t.hours<<"hours,"<<t.minutes<<"minutes";
return os;
}
//usingtime.cpp
#include<iostream>
#include"mytime.h"
int main()
{
using std::cout;
using std::endl;
Time aida(3,35);
Time tosca(2,48);
Time temp;
cout<<"Aida and Tosca:\n";
cout<<aida<<":"<<tosca<<endl;
temp=aida+tosca;
cout<<"Aida+Tosca:"<<temp<<endl;
temp=aida*1.17;
cout<<"Aida*1.17:"<<temp<<endl;
cout<<"10.0*Tosca:"<<10.0*tosca<<endl;
return 0;
}