12點半了。好久沒更新C++博文了。把一個章節看完了。接下來說下C++裡的操作符重載和以後的內容。時間晚了,可能打字沒打好。望大家見諒。
C++中有個operator操作符概念。如果想重載+運算符,那麼需要寫成operator+()。一般兩個數相加是這麼調用的:
[cpp]
a = b+c; == a = b.operator+(c);
當調用操作符,會有一個隱式的調用。把自己的對象作為操作符的對象。然後顯示調用參數c。
重點介紹友元函數。因為重載了運算符後可能出現類似:
[cpp]
a = 1.5 + c;
此時按照上面的說法。1.5不是一個對象。無法完成操作,這時候就需要友元函數了,其實友元函數就是類的非成員函數,不會隱式的將自身對象也作為參數。
然後貼三段代碼,注釋寫的還算詳細。大家可以復制後去運行下看下結果。代碼是從C++Primer Plus裡抄過來的。
mytime0.h
[cpp]
#ifndef MYTIME0_H_
#define MYTIME0_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 Sum(const Time & t)const;
// 接下來時重載+運算符的函數
Time operator+(const Time & t)const;
void Show()const;
// 重載-運算符的函數
Time operator-(const Time & t)const;
// 重載*運算符的函數
Time operator*(double n)const;
// 友元函數 類似 a+b 的原型是 a.operator+(b); 所以如果 5*a 則5沒有那個重載的函數,這時就不能使用類的成員函數了,需要友元函數來進行操作,類友元函數也就是非成員函數
friend Time operator*(double m, const Time & t){return t * m;} //內聯函數,調用該類的成員函數,這裡也就是上面那個函數。
// 友元函數。對於那些非成員重載操作符函數來說,操作符左面的操作數對應函數的第一個參數。類似 c = a+b 類似於 c = operator+(a,b)
friend std::ostream & operator<<(std::ostream & os, const Time & t);
};
#endif
mytime0.cpp
[cpp]
#include <iostream>
#include "mytime0.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::Sum(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 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 n)const
{
Time result;
long totalminutes = hours * n * 60 + minutes * n;
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;
}
void Time::Show()const
{
std::cout << hours << " hours, " << minutes << " minutes";
}
//usetime0.cpp
#include <iostream>
#include "mytime0.h"
int main()
{
using std::cout;
using std::endl;
Time planning;
Time coding(2, 40);
Time fixing(5, 55);
Time total;
cout << "planning time = ";
planning.Show();
cout << endl;
cout << "coding time = ";
coding.Show();
cout << endl;
cout << "fixing time = ";
fixing.Show();
cout << endl;
// total = coding.Sum(fixing);
// 重載加號運算符的版本
total = coding + fixing;
cout << "coding + fixing = ";
total.Show();
cout << endl;
Time morefixing(3 ,20);
cout << "more fixing time = ";
morefixing.Show();
cout << endl;
total = morefixing.operator+(total);
cout << "morefixing.operator+(total) = ";
total.Show();
cout << endl;
Time aida(3, 35);
Time tosca(2, 48);
Time temp;
cout << "Aida and TOsca:\n";
cout << aida <<"; " << tosca << endl;
temp = aida + tosca; // operator+()
cout << "Aida + Tosca: " << temp << endl;
temp = aida*1.17;
cout << "Aida *1.17: " << temp << endl;
cout << "10 * Tosca: " << 10 * tosca << endl;
return 0;
}
然後接下來說下類的強制轉換和自動轉換。
類的自動轉換就是,如果你定義了一個只接受一個參數的構造函數,那麼在調用構造函數時,如果碰到匹配的參數,直接可以將一個基本類型轉換為相應的類類型。其中有幾種隱式轉換的情況。
1.將某個對象初始化為某個值時。
2.將某個值賦值某個對象。
3.將某值傳遞給接收某對象參數的函數時。
4.返回值被聲明為某個對象的函數返回一個某值時。
5.以上情況中,如果另一個值可以轉化為某值時。
使用explicit關鍵字可以強制使用顯式構造函數,可以避免把某值轉化為某對象。
如果想進行相反的轉換,那麼就需要使用C++操作符函數-------轉換函數。轉換函數是用戶自定義的強制類型轉換。使用轉換函數得注意以下三點:
1.轉換函數必須是類方法。
2.轉換函數不能指定返回類型。
3.轉換函數不能有參數。
同樣的,也上三段代碼。
stonewt.h
[cpp]
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
enum{Lbs_per_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
void show_lbs()const;
void show_stn()const;
// 轉換函數,將對象轉換為內置類型
operator int()const;
operator double()const;
};
#endif
stonewt.cpp
[cpp]
#include <iostream>
using std::cout;
#include "stonewt.h"
Stonewt::Stonewt(double lbs)
{
stone = int(lbs)/Lbs_per_stn;
pds_left = int(lbs)%Lbs_per_stn + lbs - int(lbs);
pounds = lbs;
}
Stonewt::Stonewt(int stn, double lbs)
{
stone = stn;
pds_left = lbs;
pounds = stn * Lbs_per_stn + lbs;
}
Stonewt::Stonewt()
{
stone = pounds = pds_left = 0;
}
Stonewt::~Stonewt()
{
}
void Stonewt::show_stn()const
{
cout << stone << " stone." << pds_left << " pounds\n";
}
void Stonewt::show_lbs()const
{
cout << pounds << " pounds\n";
}
// 轉換方法 不帶參數,不帶返回值類型
Stonewt::operator int() const
{
return int(pounds+0.5);
}
Stonewt::operator double() const
{
return pounds;
}
stone.cpp
[cpp]
#include <iostream>
using std::cout;
#include "stonewt.h"
void display(const Stonewt st, int n);
int main()
{
Stonewt pavarotti = 260; //調用構造函數,因為260能轉化為浮點型
Stonewt wolfe(285.7); //類似Stonewt wolfe = 285.7;
Stonewt taft(21,8);
cout << "The tenor weighted ";
pavarotti.show_stn();
cout << "THe detective weighted ";
wolfe.show_stn();
cout << "The President weighed ";
taft.show_lbs();
pavarotti = 256.8; //構造函數進行初始化
taft = 325; //和 taft = Stonewt(325);一樣
cout << "After dinner, the tenor weighed ";
pavarotti.show_stn();
cout << "After dinner, the president weighed ";
taft.show_lbs();
display(taft, 2);
cout << "The wrestler weighted even more.\n";
display(422, 2); //將422轉化乘 Stonewt對象
cout << "No stone left unearned\n";
// 使用轉換函數將類對象轉化為基本類型
Stonewt poppins(9, 28);
double p_wt = poppins;
cout << "COnvert to double => ";
cout << "Poppins: " << p_wt << " pounds.\n";
cout << "Convert to int => ";
cout << "Poppins: " << int(poppins) << " pounds.\n";
return 0; www.2cto.com
}
void display(const Stonewt st, int n)
{
for (int i = 0; i < n; i++)
{
cout << "Wow! ";
st.show_stn();
}
}
作者:Paul_wuhaha