一,什么是運算符重載(operator overloading)
在軟件開發過程中,運算符重載(英語:operator overloading)是多態的一種。運算符重載通常只是一種語法糖,這種語法對語言的功能沒有影響,但是更方便程序員使用。讓程序更加簡潔,有更高的可讀性。
二,語法糖的現實意義
在日常工作過程中,我們讀代碼讀機會往往超過寫代碼,軟件工程是門協作的藝術
我們寫的代碼主要是給機器和人看的,給機器看的可以通過代碼測試和實際運行來進行檢驗,給人的目前還沒太好的評價方式。不過在設計一門語言的時候,方便閱讀也是語言設計重點考慮的一個方面。
運算符重載在功能實現方面並沒有任何影響,但是會給未來的自己和其他程序員帶來極大的便利。
三,operator關鍵字
operator 是 Dart 的一個關鍵字,它和運算符(如=)一起使用,表示一個 運算符重載函數,在理解時可將operator和運算符(如operator=)視為一個函數名。
使用 operator 重載運算符,是 Dar 擴展運算符功能的方法。使用 operator 擴展運算符功能的原因如下:
- 使重載后的運算符的使用方法與重載前一致
- 擴展運算符的功能只能通過函數的方式實現
對於 Dart 提供的所有操作符,通常只支持對於基本數據類型和標准庫中提供的類的操作,而對於用戶自己定義的類,如果想要通過該操作符實現一些基本操作(比如比較大小,判斷是否相等),就需要用戶自己來定義關於這個操作符的具體實現了。
比如,我們要設計一個名為“person”的類,現在要判斷person類的兩個對象p1和p2是否一樣大,我們設計的比較規則是按照其年齡來比較,那么,在設計person類的時候,就可以通過對操作符“==”進行重載,來使用操作符“==”對對象p1和p2
進行比較了(根據前面的分析,實際上比較的內容應該是person類中的數據成員“age”)。
我們上面說的對操作符“==”進行重載,說是“重載”,是由於編譯器在實現操作符“==”功能的時候,已經為我們提供了這個操作符對於一些基本數據類型的操作支持,只不過由於現在該操作符所操作的內容變成了我們自定義的數據類型(如
class),而默認情況下,該操作符是不能對我們自定義的class類型進行操作的,所以,就需要我們通過重載該操作符,給出該操作符操作我們自定義的class類型的方法,從而達到使用該操作符對我們自定義的class類型進行運算的目的。
四,實現一個操作符重載的方式通常分為兩種情況
(1)將操作符重載實現為類的成員函數; (2)操作符重載實現為非類的成員函數(即全局函數)
- 將操作符重載實現為類的成員函數;
在類體中聲明(定義)需要重載的操作符,聲明方式跟普通的成員函數一樣,只不過操作符重載函數的名字是“關鍵字 operator +以及緊跟其后的一個 Dart 預定義的操作符”,樣式如下(person是我們定義的類):
bool operator==(const person& ps) { if (this->age == ps.age) { return true; } return false; }
示例代碼(operator_test2.cpp)如下:
class Person { int age; public Person(int nAge){ this->age = nAge; } bool operator==(Person ps){ if (this.age == ps.age) { return true; } return false; } }; int main() { Person p1 = new Person(10); Person p2 = new Person(10); if (p1 == p2) { } else { } return 0; }
通過上述代碼能夠知道:因為操作符重載函數“operator==”是person類的一個成員函數,所以對象p1、p2都可以調用該函數。其中的 if (p1 == p2) 語句,相當於對象p1調用函數“operator==”,把對象p2作為一個參數傳遞給該函數,從而實現了兩個對象的比較。
- 操作符重載實現為非類的成員函數(即全局函數)
對於全局重載操作符,代表左操作數的參數必須被顯式指定。
示例代碼如下:
class Person { public int age; }; // 左操作數的類型必須被顯式指定 // 此處指定的類型為person類 bool operator==(Person p1 ,Person p2) { if (p1.age == p2.age) { return true; } else { return false; } } int main() { Person p1 = new Person(); Person p2 = new Person(); p1.age = 18; p2.age = 18; if (p1 == p2){ }else{
} return 0; }重載后操作符的操作數至少有一個是用戶定義類型;
不能違反原來操作數的語法規則;
不能創建新的操作符;
不能重載的操作符包括(以空格分隔):sizeof . .* :: ?: RTTI類型運算符
=、()、[]、以及 ->操作符只能被類的成員函數重載
五,Dart語言的運算符重載實例
-
第一步創建個類
class Role{ final String name; final int accessLevel; const Role(this.name,this.accessLevel); } main() { print('hello operator overloading'); }
-
第二步 通過函數實現Role比較
class Role{ final String name; final int accessLevel; const Role(this.name,this.accessLevel); } main() { var adminRole =new Role('管理員',3); var reporterRole = new Role('報告員',2); var userRole= new Role('用戶',1); if(adminRole.accessLevel > reporterRole.accessLevel){ print("管理員的權限大於報告員"); } if(reporterRole.accessLevel > userRole.accessLevel){ print("報告員的權限大於用戶"); } }
-
第三步 重載運算符
class Role { final String name; final int _accessLevel; const Role(this.name, this._accessLevel); bool operator >(Role Other) { return this._accessLevel > Other._accessLevel; } bool operator <(Role Other) { return this._accessLevel < Other._accessLevel; } } main() { var adminRole = new Role('管理員', 3); var reporterRole = new Role('報告員', 2); var userRole = new Role('用戶', 1); if (adminRole > reporterRole) { print("管理員的權限大於報告員"); } if (reporterRole > userRole) { print("報告員的權限大於用戶"); } }