聊聊C++ 運(yùn)算符重載知識(shí)
前言
1.運(yùn)算符重載是一種形式的C++多態(tài)。
2.重載運(yùn)算符可以使代碼看起來(lái)更加自然。
回顧類(lèi)
在正常構(gòu)造類(lèi)的時(shí)候,有些成員方法可以不用寫(xiě)出來(lái),例如在這樣一個(gè)表示時(shí)間的類(lèi)中,拷貝構(gòu)造函數(shù)只是淺拷貝,和系統(tǒng)默認(rèn)的步驟是一樣的,可以不用寫(xiě)了。 同樣,析構(gòu)函數(shù)如果在對(duì)象死亡之前沒(méi)有必須要做的事情,也可以不用寫(xiě)。
所以在下面的例子中,拷貝構(gòu)造和析構(gòu)函數(shù)可以省略。
class Time
{
public:
Time();
Time(const Time& src)
{
_hour = src._hour;
_minutes = src._minutes;
}
~Time();
private:
int _hour;
int _minutes;
};
通過(guò)示例引入運(yùn)算符重載
示例
若要將兩個(gè)等數(shù)組中各個(gè)下標(biāo)對(duì)應(yīng)的字符相加,普通寫(xiě)法為:
#include<iostream>
using namespace std;
int main(void)
{
const int SIZE = 10;
int ch1[SIZE] = { 0,1,2,3,4,5,6,7,8,9 };
int ch2[SIZE] = { 9,8,7,6,5,4,3,2,1,0 };
int ch3[SIZE];
for (int i = 0; i < SIZE; ++i)
{
ch3[i] = ch1[i] + ch2[i];
}
for (int i = 0; i < SIZE; ++i)
{
cout << ch3[i] << " ";
}
cout << endl;
return 0;
}
這樣是可以正常輸出的:

再來(lái)看看運(yùn)算符重載的示例,這里使用的是 string 類(lèi)。
#include<iostream>
#include<string>
using namespace std;
int main(void)
{
string s1 = "aaaa";
string s2 = "bbbb";
string s3 = s1 + s2;
cout << s3 << endl;
return 0;
}

這里的 s1 + s2就是運(yùn)用的加法運(yùn)算符重載,內(nèi)部實(shí)現(xiàn)也是對(duì)應(yīng)的下標(biāo)再加,但這樣簡(jiǎn)單的寫(xiě)法,強(qiáng)調(diào)了實(shí)質(zhì)。
定義
要重載運(yùn)算符,需要使用被稱(chēng)為運(yùn)算符函數(shù)的特殊函數(shù)形式。
格式:
ret_form operator op(argument-list)
例如加法運(yùn)算符:
operator +();
可重載的運(yùn)算符
這里開(kāi)個(gè)玩笑,列出這寫(xiě)可重載的,大家有興趣可以自己實(shí)現(xiàn)。

本文講述的類(lèi)
下面是文章示例的一個(gè)類(lèi):
表示一個(gè)復(fù)數(shù)
class Complex
{
public:
//默認(rèn)構(gòu)造
Complex();
//構(gòu)造函數(shù)
Complex(int a, int b)
{
_a = a;
_b = b;
}
//打印
void show()
{
cout << _a << "+" << _b << endl;
}
//析構(gòu)函數(shù)
~Complex()
{
cout << "Program Exit" << endl;
}
private:
int _a; //實(shí)部
int _b; //虛部
}
加法運(yùn)算符
如果要使用到加法,如
int main(void)
{
Complex s1(1, 2);
Complex s2(2, 3);
Complex s3 = s1 + s2;
return 0;
}
那首先要確定,我不能改變加數(shù)原本的值,其次,我需要返回一個(gè)加完之后的類(lèi)。
那重載加法運(yùn)算符聲明就可寫(xiě)成:
1.返回類(lèi)型為 類(lèi) 類(lèi)型
2.this指針聲明成const
3.第二個(gè)加數(shù)聲明為const
Complex operator +(const Complex& src)const;
函數(shù)實(shí)現(xiàn):
這里還用到了構(gòu)造函數(shù),將其構(gòu)造后返回。
//加法運(yùn)算符
Complex operator +(const Complex& src)const
{
int a = _a + src._a;
int b = _b + src._b;
return Complex(a, b);
}
使用運(yùn)算符的兩種方式:
s3和s4用到的方式都可以
Complex s1(1, 2); Complex s2(2, 3); Complex s3 = s1 + s2; Complex s4 = s1.operator+(s2);
運(yùn)行示例:
輸出了 s3 和s4, 并且析構(gòu)。

&& 運(yùn)算符
比如要寫(xiě)一個(gè)方法來(lái)判斷兩個(gè)復(fù)數(shù)的實(shí)部是否都為0.
if (s1 && s2)
{
cout << "all zero" << endl;
}
實(shí)現(xiàn):
//&&
bool operator &&(const Complex& src)const
{
return _a && src._a;
}
cout<<運(yùn)算符
想要重載輸出運(yùn)算符,首先想到的是將 cout 當(dāng)作參數(shù)傳遞給函數(shù)。
簡(jiǎn)易版(相當(dāng)于show())
//cout <<
void operator <<(ostream& out)
{
out << _a << "+" << _b << "i" << endl;
}
這樣重載的話,就只能當(dāng)作show()方法一樣調(diào)用。而不能直接使用cout。

臻享版
首先要知道,cout是一個(gè)二元運(yùn)算符,那我們傳遞參數(shù)的時(shí)候,也是傳遞兩個(gè)參數(shù),向上面的簡(jiǎn)易版,第一個(gè)參數(shù)為this指針, 第二個(gè)才是cout ,如果想把this指針移到第二個(gè)參數(shù)位置,是辦不到的,所以只能當(dāng)作show方法的樣子來(lái)寫(xiě)。
void operator <<(/*this*/ostream& out)
{
out << _a << "+" << _b << "i" << endl;
}
解決方法:
把要輸出的參數(shù)放在第二個(gè)位置。
這里就需要在類(lèi)外實(shí)現(xiàn),實(shí)現(xiàn)的方法利用友元性質(zhì),放入類(lèi)中。
如圖所示,我確實(shí)是在類(lèi)外寫(xiě)的。

運(yùn)行示例:
這里直接寫(xiě)cout << s1
int main(void)
{
Complex s1(1, 2);
Complex s2(2, 3);
Complex s3 = s1 + s2;
Complex s4 = s1.operator+(s2);
s3.show();
s4.show();
//s1.operator<<(cout);
cout << s1;
return 0;
}
沒(méi)有問(wèn)題,把 1+2i 輸出了

但如果想要連續(xù)輸出,例如:
cout << s1 << s2;
我像上面那樣寫(xiě)就不行了,因?yàn)檫@個(gè)方法的返回類(lèi)型是void,函數(shù)參數(shù)先接收 cout 和 s1, 然后返回void,將void 和 s2又當(dāng)作參數(shù)傳遞過(guò)去,顯然是不行的。
解決方法:
將這個(gè)方法的返回類(lèi)型寫(xiě)成輸出流對(duì)象, 即ostream
ostream& operator <<(ostream& out, const Complex& src)
{
out << src._a << "+" << src._b << "i" << endl;
return out;
}
同樣友元函數(shù)也寫(xiě)成:
friend ostream& operator <<(ostream& out, const Complex& src);
這樣寫(xiě)的話就可以連續(xù)輸出
示例:若要輸出三個(gè)對(duì)象
cout << s1 << s2 << s3;
運(yùn)行結(jié)果

++運(yùn)算符 前置++
前置++的意思是先 自加1,再返回。
實(shí)現(xiàn):
這里只針對(duì)復(fù)數(shù)的實(shí)部
//前置++
Complex& operator ++()
{
++_a;
return *this;
}
后置++
后置++的意思是先傳值,再自增1 。
實(shí)現(xiàn):
參數(shù)列表里的int沒(méi)有實(shí)質(zhì)意義,只是讓編譯器區(qū)分前置還是后置。
//后置++
Complex operator ++(int)
{
int tmp = _a;
_a++;
return Complex(tmp, _b);
}
練習(xí)
通過(guò)上面介紹的這些運(yùn)算符重載,可以寫(xiě)出其他一些。
這里可以實(shí)現(xiàn)有
減法運(yùn)算符、 ||運(yùn)算符、 >>運(yùn)算符 和 自減運(yùn)算符(- -)。
例如減法運(yùn)算符:和加法一樣的寫(xiě)法:
//減法運(yùn)算符
Complex operator -(const Complex& src)const
{
int a = _a - src._a;
int b = _b - src._b;
return Complex(a, b);
}
到此這篇關(guān)于C++ 運(yùn)算符重載 簡(jiǎn)介的文章就介紹到這了,更多相關(guān)C++ 運(yùn)算符重載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析string類(lèi)字符串和C風(fēng)格字符串之間的區(qū)別
string類(lèi)是標(biāo)準(zhǔn)庫(kù)的類(lèi),并不是內(nèi)置類(lèi)型,標(biāo)準(zhǔn)庫(kù)就像是我們自己定義的類(lèi)差不多的,string類(lèi)型對(duì)象沒(méi)有標(biāo)配'\0'結(jié)尾的2013-09-09
C語(yǔ)言棧與隊(duì)列相互實(shí)現(xiàn)詳解
棧和隊(duì)列,嚴(yán)格意義上來(lái)說(shuō),也屬于線性表,因?yàn)樗鼈円捕加糜诖鎯?chǔ)邏輯關(guān)系為 "一對(duì)一" 的數(shù)據(jù),但由于它們比較特殊,本章講解分別用隊(duì)列實(shí)現(xiàn)棧與用棧實(shí)現(xiàn)隊(duì)列2022-04-04
用C語(yǔ)言winform編寫(xiě)滲透測(cè)試工具實(shí)現(xiàn)SQL注入功能
本篇文章主要介紹使用C#winform編寫(xiě)滲透測(cè)試工具,實(shí)現(xiàn)SQL注入的功能。使用python編寫(xiě)SQL注入腳本,基于get顯錯(cuò)注入的方式進(jìn)行數(shù)據(jù)庫(kù)的識(shí)別、獲取表名、獲取字段名,最終獲取用戶名和密碼;使用C#winform編寫(xiě)windows客戶端軟件調(diào)用.py腳本,實(shí)現(xiàn)用戶名和密碼的獲取2021-08-08
利用Qt實(shí)現(xiàn)可擴(kuò)展對(duì)話框的示例代碼
可擴(kuò)展對(duì)話框通常用于用戶對(duì)界面有不同要求的場(chǎng)合。當(dāng)供高級(jí)用戶使用或需要更多信息時(shí),可通過(guò)某種方式的切換顯示完整對(duì)話窗體(擴(kuò)展窗體)。本文將用Qt實(shí)現(xiàn)可擴(kuò)展對(duì)話框,需要的可以參考一下2022-06-06
如何在c++中實(shí)現(xiàn)字符串分割函數(shù)split詳解
這篇文章主要給大家介紹了關(guān)于如何在c++中實(shí)現(xiàn)字符串分割函數(shù)split的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用c++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
C++類(lèi)與對(duì)象深入之運(yùn)算符重載與const及初始化列表詳解
運(yùn)算符是程序中最最常見(jiàn)的操作,例如對(duì)于內(nèi)置類(lèi)型的賦值我們直接使用=賦值即可,因?yàn)檫@些編譯器已經(jīng)幫我們做好了,但是對(duì)象的賦值呢?能直接賦值嗎2022-06-06

