運算符重載是C++的一個重要特性。有了運算符重載,在代碼編寫時能更好的實現(xiàn)封裝。
目錄
一.運算符重載介紹
二.運算符重載形式
(一).參數(shù)
(二).返回值
(三).應用
三.特殊的運算符重載
(一).默認賦值運算符重載
(二).自增運算符A++與++A
(三).流提取>>與流插入<<
四.不能進行重載的運算符
?文章來源地址http://www.zghlxwxcb.cn/news/detail-424615.html
一.運算符重載介紹
運算符重載,就是讓原本已經(jīng)存在的運算符有了新的用法和意義。
比如我們熟知的減號(-),原本是用來進行數(shù)字的相減處理。但經(jīng)過運算符重載后,它可以用來進行其他類型的相減,像時間相減、日期相減、字符相減等等。只要是你能想到的,通過運算符重載基本都能夠?qū)崿F(xiàn)。
對于C++而言,運算符重載一般是作為類的成員函數(shù)出現(xiàn)。因為當我們需要運算符重載時,往往是類中一種特殊的類型需要處理或者類本身需要處理。就像我們可能會把時間作為一個類,里面有小時、分鐘、秒。如果讓時間相減,那么減號的參數(shù)類型就變成了時間類。因此,重載最好作為類的成員函數(shù)出現(xiàn),減少在我們調(diào)用運算符重載時發(fā)生沖突的可能。
二.運算符重載形式
[返回值] operator[運算符] (參數(shù)...) { ... };
(一).參數(shù)
第一點:
這里我們必須注意的是,重載的參數(shù)個數(shù)必須與運算符原意的個數(shù)一致。比如+號的參數(shù)就是左加數(shù)和右加數(shù)兩個。那么當我們重載加號時也要保證有左右兩個加數(shù)作為參數(shù)。
第二點:
重載作為普通函數(shù)時:
單目:右操作數(shù)是形參;雙目:左邊形參作為運算符左操作數(shù),右邊形參是右操作數(shù)。
重載作為類的成員函數(shù)時:
如果運算符參數(shù)只有一個,那么不需要寫參數(shù);如果運算符參數(shù)有兩個,那么只需要寫一個參數(shù)。
因為類的成員函數(shù)默認有一個this指針。它會直接指向類本身。換句話說,當我們寫出運算符重載時,有一個參數(shù)就已經(jīng)被this指針包含了。
單目運算符,this所指向運算符右參數(shù),因為單目運算符的參數(shù)一般都在右邊。
雙目運算符,this指向運算符左參數(shù)。
以減號為例,兩個時間類a和b相減時。如果是a - b,那么this指針指向a,反之則指向b。在聲明函數(shù)時,我們只需要寫右參數(shù)即可。a - b的話只需要寫 int operator-(Time b);
當然,單目運算符由于只有一個參數(shù),且該參數(shù)被this所指向,那么我們無需聲明任何參數(shù)即可。
(二).返回值
運算符的返回值類型取決于該重載函數(shù)的作用是什么。
比如a + b的作用是得到一個加數(shù),那么返回值就是a+b的值。a += b的作用是讓a的值改變,既然是讓參數(shù)a的值改變,那么就無需返回值。
還有就是如果我們需要運算符支持多次操作那么也需要返回值。比如流插入運算符<<。我們可能需要多次進行插入,像cout << a << b << c;之類就需要返回流ostream本身以便于之后的流插入工作。
(三).應用
下面,我來為大家展示幾種運算符重載方式:
加號(雙目):
class Time
{
int _hour;
int _min;
int _sec;
public:
Time(int hour = 0, int min = 0, int sec = 0)
{
_hour = hour;
_min = min;
_sec = sec;
}
void Print()
{
cout << _hour << ":" << _min << ":" << _sec << endl;
}
Time operator+(int min)//加分鐘
{
Time t(*this);//因為是+號,規(guī)定不能改變左右參數(shù)的值,所以使用t來取和用以返回。
t._min += min;
if (t._min > 59)//檢查時間正確性
{
t._hour += (t._min / 60);
if (t._hour > 23)
t._hour /= 24;
t._min %= 60;
}
return t;
}
};
int main()
{
Time a(10, 30, 30);
(a + 140).Print();
return 0;
}
?自增(單目):
class Time
{
int _hour;
int _min;
int _sec;
public:
Time(int hour = 0, int min = 0, int sec = 0)
{
_hour = hour;
_min = min;
_sec = sec;
}
void Print()
{
cout << _hour << ":" << _min << ":" << _sec << endl;
}
int& operator++()// ++a和a++分別如何我們之后會講到,這里使用++a
{
return _hour += 1;//為方便演示,讓小時+1,但不再判斷時間正確性
}
};
int main()
{
Time a(10, 30, 30);
++a;
a.Print();
return 0;
}
三.特殊的運算符重載
(一).默認賦值運算符重載
即便我們沒有手動定義賦值運算符重載,C++也為我們提供了默認函數(shù)。
在默認賦值重載中,內(nèi)置類型按字節(jié)拷貝,自定義類型會去調(diào)自己的默認賦值重載。這點與默認拷貝構造極為相似,不懂的可以看看這篇文章:詳解析構函數(shù)、拷貝構造函數(shù)
因此,當我們的類中只有int、char、double之類內(nèi)置類型時,無需再寫賦值重載。
但是,如果有指針、malloc、new之類指向地址、手動開辟空間的,一般情況下還是需要手寫重載的。
總而言之,默認賦值重載只能進行淺拷貝,是否需要手動去寫要根據(jù)類的成員類型判斷。
class Time
{
int _hour;
int _min;
int _sec;
public:
Time(int hour = 0, int min = 0, int sec = 0)
{
_hour = hour;
_min = min;
_sec = sec;
}
void Print()
{
cout << _hour << ":" << _min << ":" << _sec << endl;
}
};
int main()
{
Time a;
Time b(20, 10, 50);
a.Print();
a = b;//調(diào)用默認賦值重載
a.Print();
return 0;
}
?值得注意的一點是:
我們需要分清楚賦值重載與拷貝構造的區(qū)別。
拷貝構造只能發(fā)生在對象被定義時,而賦值則是在對象已經(jīng)被定義完畢后。
void main()
{
Time A;
Time T = A;//拷貝構造
Time B;
B = A;//賦值重載
}
(二).自增運算符A++與++A
因為單目運算符重載的this指針指向右邊,所以按正常寫法我們寫出來的是++A。
C++規(guī)定,A++的寫法是在正常++運算重載基礎上,在參數(shù)上寫一個int類型的參數(shù)。
方式如下:
class Time
{
int _hour;
int _min;
int _sec;
public:
Time(int hour = 0, int min = 0, int sec = 0)
{
_hour = hour;
_min = min;
_sec = sec;
}
void Print()
{
cout << _hour << ":" << _min << ":" << _sec << endl;
}
//為方便演示,讓小時+1,但不再判斷時間正確性
Time& operator++()// ++A
{
_hour += 1;
return (*this);//因為自增直接返回this用引用接收
}
Time operator++(int)//A++,參數(shù)寫int或int i都可以
{
Time ret(*this);
_hour += 1;
return ret;//需要返回this自增之前的結果,所以用臨時變量返回
}
};
int main()
{
Time a(10, 30, 30);
//(++a).Print();
//a.Print();
(a++).Print();
a.Print();
return 0;
}
?
?
(三).流提取>>與流插入<<
對于流而言,因為是雙目運算符,this指針本應該指向左邊的類,但左操作數(shù)是一個流,又與this的類型沖突。那么就會出現(xiàn)很奇怪的現(xiàn)象:
因為this指針會默認指向類,而我們需要讓左參數(shù)指向流,右參數(shù)指向類。所以重載就不能作為類的成員函數(shù)出現(xiàn)了。
這時,就需要用到友元函數(shù)friend。友元函數(shù)本身是一個普通函數(shù),但是作為類的友元,能夠調(diào)用類內(nèi)的成員,包括private。而且參數(shù)不用被類限制為第一個必須是this所指的對象本身。
使用時,我們只需要在類內(nèi)聲明有個友元函數(shù)即可。
#include"head.h"
class Time
{
friend ostream& operator<<(ostream& out, Time& t);//友元函數(shù),聲明
friend istream& operator>>(istream& in, Time& t);
int _hour;
int _min;
int _sec;
public:
Time(int hour = 0, int min = 0, int sec = 0)
{
_hour = hour;
_min = min;
_sec = sec;
}
};
ostream& operator<<(ostream& out, Time& t)//流插入
{
out << t._hour << ":" << t._min << ":" << t._sec << endl;
return out;
}
istream& operator>>(istream& in, Time& t)//流提取
{
in >> t._hour >> t._min >> t._sec;
return in;
}
int main()
{
Time a;
cin >> a;
cout << a;
return 0;
}
?
四.不能進行重載的運算符
在C++中有幾種運算符不能進行重載
.* | 任意字符出現(xiàn)零次或多次 |
:: | 域作用符 |
sizeof | 大小 |
? : | 三目運算符 |
. | 點運算符 |
?文章來源:http://www.zghlxwxcb.cn/news/detail-424615.html
?
- “優(yōu)良設計創(chuàng)造價值的速度,快于其增加成本的速度。”——托馬斯·C.蓋勒(Thomas C.Gale)
?如有錯誤,敬請斧正
?
?
到了這里,關于C++語法——詳解運算符重載的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!