玩轉C++運算符重載
運算符重載語法:返回值類型 operator運算符(參數列表) { 代碼邏輯。。。 }
C++中的運算符重載是通過函數來實現的,可以將重載的運算符看作是類成的一個成員函數,向普通函數一樣調用。如重載String類的 + 運算符,調用的時候可以這樣:
class { // ..... String operator+(const String &str) { .... } } String str1 = "hello "; String str2 = "cplusplus"; String str3 = str1.operator+(str2);從上述代碼中可以看出,operator+就像是String類的一個函數,可以像普通函數一樣調用,將要相加的字符串對象作為實參傳遞給函數即可。所以從這可以得出一個函數重載的步聚:(以上述+重載為例)
1、寫出運算符的函數原型
str1.operator+(str2);
從這可以得知,+ 需要兩個操作數,str1和str2(即兩個字符串對象),返回值類型為String對象(加法運算後的結果)。由於是作為類的成員函數重載,所以str1在進行 + 運算時作為this指針傳給函數,函數隻需要一個參數即可,即被相加的字符串對象str2。
2、寫出函數聲明
從函數原型可以得出函數聲明:String operator+(const String &str);
3、實現函數細節
String String::operator+(const String &str) { if (str.buff == nullptr) { return *this; } size_t totallen = str.len + this->len + 1; char *buff = new char[totallen]; strcpy(buff, this->buff); strcat(buff, str.buff); String temp(buff); return temp; }
下麵這個示例重載了字符串操作的常用操作符:
// // String.h // C++運算符重載 // // Created by 楊信 on 14-5-8. // Copyright (c) 2014年 yangxin. All rights reserved. // #ifndef __C______String__ #define __C______String__ #include <iostream> using namespace std; class String { private: char *buff; size_t len; public: String(); // 用一個字符串初始化對象 String(const char *buff); // 拷貝構造 String(const String &str); // 析構 ~String(); // 設置字符串內容 void setString(const char *buff); // 獲取字符串的長度 size_t length() const; // 獲取字符串內容 char * getStr() const; // 比較兩個字符串是否相等 bool operator==(String &str); // 比較兩個字符串是否不相等 bool operator!=(String &str); // 比較兩個字符串的大小 bool operator>(String &str); // 比較兩個字符串的大小 bool operator<(String &str); // 獲取或修改字符串中的某一個字符 char& operator[](int index); // 賦值構造函數 String& operator=(const String &str); // 兩個字符串相加 String operator+(const String &str); // 字符串累加 String& operator+=(const String &str); // 從輸入流中獲取字符串 friend istream& operator>>(istream &input, String &str); // 將字符串輸出到輸出流 friend ostream& operator<<(ostream &output, const String &str); }; #endif /* defined(__C______String__) */ // // String.cpp // C++運算符重載 // // Created by 楊信 on 14-5-8. // Copyright (c) 2014年 yangxin. All rights reserved. // #include "String.h" #include <string> #include <cassert> #include <cmath> String::String() { this->buff = nullptr; this->len = 0; } // 用一個字符串初始化對象 String::String(const char *buff):buff(nullptr), len(0) { setString(buff); } // 拷貝構造 String::String(const String &str) { setString(str.buff); } // 析構 String::~String() { // 釋放內存 if (this->buff != nullptr) { delete[] buff; buff = nullptr; len = 0; } } void String::setString(const char *buff) { if (buff == nullptr) { return; } if (this->buff != nullptr) { delete[] this->buff; this->buff = nullptr; this->len = 0; } size_t len = strlen(buff); this->buff = new char[len + 1]; this->len = len; strcpy(this->buff, buff); } // 獲取字符串的長度 size_t String::length() const { return this->len; } // 獲取字符串內容 char * String::getStr() const { return this->buff; } // 獲取或修改字符串中的某一個字符 char& String::operator[](int index) { assert(index < this->len); return this->buff[index]; } // 比較兩個字符串是否相等 bool String::operator==(String &str) { if (this->len != str.len) { return false; } for (int i = 0; i < this->len; ++i) { if (this->buff[i] != str[i]) { return false; } } return true; } // 比較兩個字符串是否不相等 bool String::operator!=(String &str) { return !(*this == str); } // 比較兩個字符串的大小 bool String::operator>(String &str) { char *pstr = this->buff; char *pstr2 = str.buff; while (*pstr != '\0' && *pstr2 != '\0') { if (*pstr > *pstr2) { return true; } pstr++; pstr2++; } return false; } // 比較兩個字符串的大小 bool String::operator<(String &str) { return !(*this > str); } // 賦值構造函數 String& String::operator=(const String &str) { setString(str.buff); return *this; } // 兩個字符串相加 String String::operator+(const String &str) { if (str.buff == nullptr) { return *this; } size_t totallen = str.len + this->len + 1; char *buff = new char[totallen]; strcpy(buff, this->buff); strcat(buff, str.buff); String temp(buff); return temp; } // 字符串累加 String& String::operator+=(const String &str) { if (str.buff == nullptr) { return *this; } // 創建一個臨時緩衝區,存儲對象本身的字符串和相加的字符串 size_t len = this->len + str.length(); char *temp = new char[len + 1]; strcpy(temp, this->buff); strcat(temp, str.buff); // 設置新的字符串給對象本身 setString(temp); return *this; } // 從輸入流中獲取字符串 istream& operator>>(istream &input, String &str) { // 在堆區創建臨時緩衝區,接收用戶輸入 int size = 1024 * 10; char *tempbuff = new char[size]; memset(tempbuff, 0, size); // 獲取用戶輸入 input.getline(tempbuff, size); // 將臨時緩衝中的字符串保存到str對象的字符串緩衝區中 str.setString(tempbuff); // 釋放臨時緩衝區數據 delete[] tempbuff; tempbuff = nullptr; return input; } // 將字符串輸出到輸出流 ostream& operator<<(ostream &output, const String &str) { output << str.getStr(); return output; } // 測試用例 // // main.cpp // String(運算符重載) // // Created by 楊信 on 14-5-8. // Copyright (c) 2014年 yangxin. All rights reserved. // #include <iostream> #include "String.h" #include <cmath> using namespace std; int main(int argc, const char * argv[]) { // 初始化 String str1("helloz"); String str2("helloz"); // 獲取字符中內容 cout << str1.getStr() << endl; // 獲取字符串的長度 cout << "長度:" << str1.length() << endl; // 獲取第字符串中的第一個字符 cout << "第1個字符:" << str1[0] << endl; // 比較兩個字符串是否相等,相等返回1,否則返回0 bool isequal = str1 == str2; cout << isequal << endl; // 比較兩個字符串的大小,str1大於str2返回1,否則返回0 cout << (str1 > str2) << endl; // 修改字符串中的第2個字符為C String s = "Hello"; s[1] = 'C'; cout << s << endl; // 測試用一個字符串去初始化另外一個字符串 String str3 = str2; cout << str3.getStr() << endl; String str4; str4 = str3; cout << str4.getStr() << endl; // 測試兩個字符串相加 String str5 = str1 + str2; cout << &str5 << endl; cout << str5.getStr() << endl; // 測試字符串連等 String str6; String str7 = str6 = str5; cout << str6.getStr() << " | " << str7.getStr() << endl; // 測試字符串累加 String str8 = "i love c++ "; str8 += "i love c "; cout << str8.getStr() << endl; // 從輸入流讀取字符串 String str9; cout << "Please a string:"; cin >> str9; // 將字符串輸出到輸出流 cout << str9 << endl; return 0; }運算符重載注意事項:
- 友元函數重載運算符時需要傳遞所有操作數
- 成員函數重載,會將操作數本身做為this指針作為參數傳入函數,如果是多元操作符,隻需與它被操作的數傳入函數即可
-
= 號重載時,如果對象中有新分配內存的成員,要先delete,再new,如果要支持連等操作,需要返回對象本身的引用
-
函數返回值作左值時,返回值必須為引用
- 隻有C++預定義的操作符集中的操作符才可以被重載(不能自己隨便寫一個操作符,如:+-)
- 重載操作符不能改變操作符的優先級,例如:先乘徐,後加減
- 重載操作符不能改變操作數的個數
以下幾種運算符不能被重載:
- . :成員選擇運算符
- :: :作用域運算符
- * : 指針運算符
- # :預處理標誌
- ?: :三目運算符,沒有確定性,重載沒有意義
最後更新:2017-04-03 12:56:35
上一篇:
Netty4詳解二:開發第一個Netty應用程序
下一篇:
如何解決每次打開office2007、2010、2013都會出現正在配置
網絡攻擊更難預料,IoT到底是福是禍?
智慧汽車價值何在?車聯網和無人車的中間形態
Ubuntu 12.10打破PC與網絡藩籬 整合雲端應用
成都雲棲大會,阿裏1582.73億營收背後的持續交付如何玩?
數據結構之AVL樹
Android開發7——android.database.CursorIndexOutOfBoundsException:Index -1 requested, with a size of 1
機房收費係統之周結賬單
6月30日雲棲精選夜讀:程序員技術與文藝的PK,來首屆阿裏巴巴研發效能嘉年華
HttpWebRequest的GetRespons偶爾超時、死掉的原因及解決辦法
從機器學習談起