本文主要介紹C++中的重載操做符(operator)的相關知識。ios
1. 概述
1.1 what
operator 是C++的一個關鍵字,它和運算符(如=)一塊兒使用,表示一個運算符重載函數,在理解時可將operator和運算符(如operator=)視爲一個函數名。函數
使用operator重載運算符,是C++擴展運算符功能的方法。使用operator擴展運算符功能的緣由以下:this
使重載後的運算符的使用方法與重載前一致
擴展運算符的功能只能經過函數的方式實現(實際上,C++中各類「功能」都是由函數實現的)
1.2 why
對於C++提供的全部操做符,一般只支持對於基本數據類型和標準庫中提供的類的操做,而對於用戶本身定義的類,若是想要經過該操做符實現一些基本操做(好比比較大小,判斷是否相等),就須要用戶本身來定義關於這個操做符的具體實現了。spa
好比,咱們要設計一個名爲「person」的類,如今要判斷person類的兩個對象p1和p2是否同樣大,咱們設計的比較規則是按照其年齡來比較,那麼,在設計person類的時候,就能夠經過對操做符「==」進行重載,來使用操做符「==」對對象p1和p2進行比較了(根據前面的分析,實際上比較的內容應該是person類中的數據成員「age」)。設計
咱們上面說的對操做符「==」進行重載,說是「重載」,是因爲編譯器在實現操做符「==」功能的時候,已經爲咱們提供了這個操做符對於一些基本數據類型的操做支持,只不過因爲如今該操做符所操做的內容變成了咱們自定義的數據類型(如class),而默認狀況下,該操做符是不能對咱們自定義的class類型進行操做的,因此,就須要咱們經過重載該操做符,給出該操做符操做咱們自定義的class類型的方法,從而達到使用該操做符對咱們自定義的class類型進行運算的目的。對象
1.3 how
實現一個操做符重載的方式一般分爲兩種狀況:編譯器
將操做符重載實現爲類的成員函數;
操做符重載實現爲非類的成員函數(即全局函數)。
1.3.1 將操做符重載實現爲類的成員函數
在類體中聲明(定義)須要重載的操做符,聲明方式跟普通的成員函數同樣,只不過操做符重載函數的名字是「關鍵字 operator +以及緊跟其後的一個C++預約義的操做符」,樣式以下(person是咱們定義的類):string
bool operator==(const person& ps)
{
if (this->age == ps.age)
{
return true;
}
return false;
}
示例代碼(operator_test2.cpp)以下:it
#include <iostream>
using namespace std;
class person
{
private:
int age;
public:
person(int nAge)
{
this->age = nAge;
}
bool operator==(const person& ps)
{
if (this->age == ps.age)
{
return true;
}
return false;
}
};
int main()
{
person p1(10);
person p2(10);
if (p1 == p2)
{
cout << "p1 is equal with p2." << endl;
}
else
{
cout << "p1 is not equal with p2." << endl;
}
return 0;
}
編譯並運行上述代碼,結果以下:io
經過上述結果可以知道:由於操做符重載函數「operator==」是person類的一個成員函數,因此對象p一、p2均可以調用該函數。其中的 if (p1 == p2) 語句,至關於對象p1調用函數「operator==」,把對象p2做爲一個參數傳遞給該函數,從而實現了兩個對象的比較。
1.3.2 操做符重載實現爲非類的成員函數(即全局函數)
對於全局重載操做符,表明左操做數的參數必須被顯式指定。
示例代碼以下:
#include <iostream>
using namespace std;
class person
{
public:
int age;
};
// 左操做數的類型必須被顯式指定
// 此處指定的類型爲person類
bool operator==(person const& p1 ,person const& p2)
{
if (p1.age == p2.age)
{
return true;
}
else
{
return false;
}
}
int main()
{
person p1;
person p2;
p1.age = 18;
p2.age = 18;
if (p1 == p2)
{
cout << "p1 is equal with p2." << endl;
}
else
{
cout << "p1 is NOT equal with p2." << endl;
}
return 0;
}
編譯並運行上述代碼,結果以下:
1.3.4 操做符重載的方式選擇
能夠根據如下因素,肯定把一個操做符重載爲類的成員函數仍是全局函數:
若是一個重載操做符是類成員,那麼只有當與它一塊兒使用的左操做數是該類的對象時,該操做符纔會被調用;而若是該操做符的左操做數肯定爲其餘的類型,則操做符必須被重載爲全局函數;
C++要求'='、'[]'、'()'、'->'操做符必須被定義爲類的成員操做符,把這些操做符經過全局函數進行重載時會出現編譯錯誤
若是有一個操做數是類類型(如string類),那麼對於對稱操做符(好比==操做符),最好經過全局函數的方式進行重載。
1.3.5 操做符重載的限制
實現操做符重載時,須要注意:
重載後操做符的操做數至少有一個是用戶定義類型; 不能違反原來操做數的語法規則; 不能建立新的操做符; 不能重載的操做符包括(以空格分隔):sizeof . .* :: ?: RTTI類型運算符 =、()、[]、以及 ->操做符只能被類的成員函數重載 1.3.6 操做符重載的詳細用法 賦值運算符的重載函數(operator=),點擊此處