【項目2拓展2(思考)】這個思考題吊一下大家的胃口:設定義了兩個分數類的對象,如CFraction c1, c2。如果定義了int i,我們能用cin>>i>>j;在鍵盤上輸入i和j的值,是否期望用cin>>c1>>c2;輸入分數呢?同理,用cout<<c1<<c2;進行輸出,可以嗎?進一步,用c1+c2得到新的一個分數,用c1/c2實現兩個分數的除法,以及其他加、減、比較、求倒數等也是理所當然的。實際上,要自定義分數類,這些直觀的基本運算應該要實現,這叫運算符的重載。本任務中用amplify()給出了“放大”運算的一種實現方案,更多內容值得期待地。
首先要說明:有的C++編譯系統(如VC++6.0)沒有完全實現C++標准,它所提供的後綴.h的頭文件不支持把成員函數重載為友元函數,因此在VC++6.0,應把程序的頭兩行:
#include <iosteam>
using namespace std;
改為一行:#include <iosteam.h> //C語言的風格
這是我自己編寫的有關運算符重載的程序:
[cpp]
#include <iostream.h>
enum style_enum{zero, one, two, three };
class CFraction
{private:
int nume; // 分子
int deno; // 分母
public:
CFraction(int nu=0,int de=1):nume(nu),deno(de){} //構造函數,初始化用
void simplify(); //化簡(使分子分母沒有公因子)
//輸入輸出重載
friend ostream& operator<<(ostream &out,const CFraction &cf);
friend istream& operator>>(istream &in,CFraction &cf);
//加減乘除,結果需要化簡
friend CFraction operator+(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator-(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator*(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator/(const CFraction &lcf,const CFraction &rcf);
//關系運算符
friend bool operator>(const CFraction &lcf,const CFraction &rcf);
friend bool operator<(const CFraction &lcf,const CFraction &rcf);
friend bool operator>=(const CFraction &lcf,const CFraction &rcf);
friend bool operator<=(const CFraction &lcf,const CFraction &rcf);
friend bool operator==(const CFraction &lcf,const CFraction &rcf);
friend bool operator!=(const CFraction &lcf,const CFraction &rcf);
//取+、-一目運算符
CFraction operator+();
CFraction operator-();
};
void CFraction::simplify()
{
int v1 = nume;
int v2 = deno;
while(v2)
{
int temp = v2;
v2 = v1 % v2;
v1 = temp;
}
nume /= v1;
deno /= v1;
if(deno < 0)
{
deno = -deno;
nume = -nume;
}
}
//輸出重載
ostream& operator<<(ostream &out,const CFraction &cf)
{
out << cf.nume << '/' << cf.deno;
return out;
}
//輸入重載
istream& operator>>(istream &in,CFraction &cf)
{
char ch;
while(1)
{
in >> cf.nume >> ch >> cf.deno;
if(cf.deno == 0)
cerr << "分母為0請重新輸入\n";
else if(ch != '/')
cerr << "格式錯誤(形如m/n)請重新輸入\n";
else break;
}
return in;
}
//加法重載
CFraction operator+(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno + lcf.deno*rcf.nume;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//減法重載
CFraction operator-(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno - rcf.nume*lcf.deno;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//乘法重載
CFraction operator*(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.nume;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//除法重載
CFraction operator/(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno;
cf.deno = lcf.deno*rcf.nume;
cf.simplify();
return cf;
}
//取正重載
CFraction CFraction::operator+()
{
simplify();
if(nume < 0)
nume = -nume;
return *this;
}
//取負重載
CFraction CFraction::operator-()
{
simplify();
nume = -nume;
return *this;
}
//大於號重載
bool operator>(const CFraction &lcf,const CFraction &rcf)
{
int l_nume = lcf.nume * rcf.deno;
int r_nume = rcf.nume * lcf.deno;
int common_deno = lcf.deno * rcf.deno;
if((l_nume-r_nume) * common_deno > 0) return true;
return false;
}
//小於號重載
bool operator<(const CFraction &lcf,const CFraction &rcf)
{
return !(lcf > rcf);
}
//等於重載
bool operator==(const CFraction &lcf,const CFraction &rcf)
{
return lcf.nume==rcf.nume && lcf.deno == rcf.deno;
}
//不等於重載
bool operator!=(const CFraction &lcf,const CFraction &rcf)
{
return !(lcf==rcf);
}
//
bool operator>=(const CFraction &lcf,const CFraction &rcf)
{
if(lcf < rcf) return false;
return true;
}
//
bool operator<=(const CFraction &lcf,const CFraction &rcf)
{
if(lcf > rcf) return false;
return true;
}
int main()
{
CFraction cf1;
CFraction cf2;
cin >> cf1 >> cf2;
cout << "cf1: "<< cf1 << '\t' << "cf2: "<< cf2 << endl
<< "cf1 + cf2 : " << cf1+cf2 << endl
<< "cf1 - cf2 : " << cf1-cf2 << endl
<< "cf1 * cf2 : " << cf1*cf2 << endl
<< "cf1 / cf2 : " << cf1/cf2 << endl
<< " +cf1 : " << +cf1 << endl
<< " -cf1 : " << -cf1 << endl
<< " +cf2 : " << +cf2 << endl
<< " -cf2 : " << -cf2 << endl
<< " cf1 > cf2? 1/YES 0/NO " << (cf1 > cf2) << endl
<< " cf1 < cf2? 1/YES 0/NO " << (cf1 < cf2) << endl
<< " cf1 == cf2? 1/YES 0/NO " << (cf1 == cf2) << endl
<< " cf1 != cf2? 1/YES 0/NO " << (cf1 != cf2) << endl
<< " cf1 >= cf2? 1/YES 0/NO " << (cf1 >= cf2) << endl
<< " cf1 <= cf2? 1/YES
return 0;
}
#include <iostream.h>
enum style_enum{zero, one, two, three };
class CFraction
{private:
int nume; // 分子
int deno; // 分母
public:
CFraction(int nu=0,int de=1):nume(nu),deno(de){} //構造函數,初始化用
void simplify(); //化簡(使分子分母沒有公因子)
//輸入輸出重載
friend ostream& operator<<(ostream &out,const CFraction &cf);
friend istream& operator>>(istream &in,CFraction &cf);
//加減乘除,結果需要化簡
friend CFraction operator+(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator-(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator*(const CFraction &lcf,const CFraction &rcf);
friend CFraction operator/(const CFraction &lcf,const CFraction &rcf);
//關系運算符
friend bool operator>(const CFraction &lcf,const CFraction &rcf);
friend bool operator<(const CFraction &lcf,const CFraction &rcf);
friend bool operator>=(const CFraction &lcf,const CFraction &rcf);
friend bool operator<=(const CFraction &lcf,const CFraction &rcf);
friend bool operator==(const CFraction &lcf,const CFraction &rcf);
friend bool operator!=(const CFraction &lcf,const CFraction &rcf);
//取+、-一目運算符
CFraction operator+();
CFraction operator-();
};
void CFraction::simplify()
{
int v1 = nume;
int v2 = deno;
while(v2)
{
int temp = v2;
v2 = v1 % v2;
v1 = temp;
}
nume /= v1;
deno /= v1;
if(deno < 0)
{
deno = -deno;
nume = -nume;
}
}
//輸出重載
ostream& operator<<(ostream &out,const CFraction &cf)
{
out << cf.nume << '/' << cf.deno;
return out;
}
//輸入重載
istream& operator>>(istream &in,CFraction &cf)
{
char ch;
while(1)
{
in >> cf.nume >> ch >> cf.deno;
if(cf.deno == 0)
cerr << "分母為0請重新輸入\n";
else if(ch != '/')
cerr << "格式錯誤(形如m/n)請重新輸入\n";
else break;
}
return in;
}
//加法重載
CFraction operator+(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno + lcf.deno*rcf.nume;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//減法重載
CFraction operator-(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno - rcf.nume*lcf.deno;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//乘法重載
CFraction operator*(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.nume;
cf.deno = lcf.deno*rcf.deno;
cf.simplify();
return cf;
}
//除法重載
CFraction operator/(const CFraction &lcf,const CFraction &rcf)
{
CFraction cf;
cf.nume = lcf.nume*rcf.deno;
cf.deno = lcf.deno*rcf.nume;
cf.simplify();
return cf;
}
//取正重載
CFraction CFraction::operator+()
{
simplify();
if(nume < 0)
nume = -nume;
return *this;
}
//取負重載
CFraction CFraction::operator-()
{
simplify();
nume = -nume;
return *this;
}
//大於號重載
bool operator>(const CFraction &lcf,const CFraction &rcf)
{
int l_nume = lcf.nume * rcf.deno;
int r_nume = rcf.nume * lcf.deno;
int common_deno = lcf.deno * rcf.deno;
if((l_nume-r_nume) * common_deno > 0) return true;
return false;
}
//小於號重載
bool operator<(const CFraction &lcf,const CFraction &rcf)
{
return !(lcf > rcf);
}
//等於重載
bool operator==(const CFraction &lcf,const CFraction &rcf)
{
return lcf.nume==rcf.nume && lcf.deno == rcf.deno;
}
//不等於重載
bool operator!=(const CFraction &lcf,const CFraction &rcf)
{
return !(lcf==rcf);
}
//
bool operator>=(const CFraction &lcf,const CFraction &rcf)
{
if(lcf < rcf) return false;
return true;
}
//
bool operator<=(const CFraction &lcf,const CFraction &rcf)
{
if(lcf > rcf) return false;
return true;
}
int main()
{
CFraction cf1;
CFraction cf2;
cin >> cf1 >> cf2;
cout << "cf1: "<< cf1 << '\t' << "cf2: "<< cf2 << endl
<< "cf1 + cf2 : " << cf1+cf2 << endl
<< "cf1 - cf2 : " << cf1-cf2 << endl
<< "cf1 * cf2 : " << cf1*cf2 << endl
<< "cf1 / cf2 : " << cf1/cf2 << endl
<< " +cf1 : " << +cf1 << endl
<< " -cf1 : " << -cf1 << endl
<< " +cf2 : " << +cf2 << endl
<< " -cf2 : " << -cf2 << endl
<< " cf1 > cf2? 1/YES 0/NO " << (cf1 > cf2) << endl
<< " cf1 < cf2? 1/YES 0/NO " << (cf1 < cf2) << endl
<< " cf1 == cf2? 1/YES 0/NO " << (cf1 == cf2) << endl
<< " cf1 != cf2? 1/YES 0/NO " << (cf1 != cf2) << endl
<< " cf1 >= cf2? 1/YES 0/NO " << (cf1 >= cf2) << endl
<< " cf1 <= cf2? 1/YES
return 0;
}