c++中過載運算子的使用:
使用者定義的型別,如:字串,日期,複數,聯合體以及檔案常常過載二元 + 操作符以實現物件的連線,附加或合併機制。但是要正確實現 + 操作符會給設計,實現和效能帶來一定的挑戰。本文將概要性地介紹如何選擇正確的策略來為使用者定義型別過載這個操作符。
考慮如下的表示式: int x=4+2;
內建的 + 操作符有兩個型別相同的運算元,相加並返回右值 6,然後被賦值給 x。我們可以斷定內建的 + 是乙個二元的,對稱的,可交換的操作符。它產生的結果的型別與其運算元型別相同。按照這個規測,當你為某個使用者定義型別過載操作符時,也應該遵循相應內建操作符的特徵。
為使用者定義型別過載 + 操作符是很常見的程式設計任務。儘管 c++ 提供了幾種實現方法,但是它們容易使人產生設計上的誤解,這種誤解常常影響**的正確性,效能以及與標準庫元件之間的相容性。
下面我們就來分析內建操作符的特徵並嘗試模仿其相應的過載機制。
第一步:在成員函式和非成員函式之間選擇
你可以用類成員函式的方式實現二元操作符如:+、- 以及 ==,例如:
class string
;
這個方法是有問題的。相對於其內建的操作符來說,過載的操作符在這裡不具有對稱性;它的兩個引數乙個型別為:const string * const(這個引數是隱含的),另乙個型別為:const string &。因此,一些 stl 演算法和容器將無法正確處理這樣的物件。
另外乙個可選方法是把過載操作符 + 定義為乙個外部(extern)函式,該函式帶兩個型別相同的引數:
string operator + (const string & s1, const string s2);
這樣一來,類 string 必須將該過載操作符宣告為友元:
class string
;
第二步:返回值的兩難選擇如前所述,內建操作符 + 返回右值,其型別與運算元相同。但是在呼叫者堆疊裡返回乙個物件效率很低,處理大型物件時尤其如此。那麼能不能返回乙個指標或引用呢?答案是不行。因為返回指標破壞引數型別與返回值型別應該相同的規則。更糟的是,鏈結多個表示式將成為不可能:
string s1,s2,s3;
string res;
res=s1+s2+s3; // 不可能用 string* 作為返回值
雖然有乙個辦法可以定義額外的 + 操作符過載版本,但這個辦法是我們不希望用的,因為返回的指標必須指向動態分配的物件。這樣的話,如果呼叫者釋放(delete)返回的指標失敗,那麼將導致記憶體洩漏。顯然,返回 string* 不是乙個好主意。
那麼返回 string& 好不好呢?返回的引用必須一定要是乙個有效的 string。它避免了使用動態物件分配,該方法返回的是乙個本地靜態物件的引用。靜態物件確實解決了記憶體洩漏問題,但這個方法的可行性仍然值得懷疑。在乙個多執行緒應用中,兩個執行緒可能會併發呼叫 + 操作符,因此造成 string 物件的混亂。而且,因為靜態物件總是保留其呼叫前的狀態,所以有必要針對每次 + 操作符的呼叫都清除該靜態 string 物件。由此看來,在堆疊上返回結果仍然是最安全和最簡單的解決方案。
C 過載運算子
運算子過載是一種形式的c 多型。在c 中,編譯器有能力把乙個由資料 物件和操作符共同組成的表示式,解釋為對乙個全域性或成員函式的呼叫。該全域性或成員函式被稱為操作符函式,通過重定義操作符函式,可以實現針對自定義型別 結構,類 的運算法則,並使之與內建型別一樣參與各種表示式。過載運算子可使 看起來更加...
C 過載運算子
本文主要講述加號運算子 自增運算子 流提取運算子運 流插入運算子 先給出vector類 class vector 建構函式 vector const vector v 拷貝建構函式 vector operator const vector v 過載 vector operator 過載前置自增運算子...
C 過載運算子
過載的運算子是帶有特殊名稱的函式,函式名是由關鍵字 operator 和其後要過載的運算子符號構成的。與其他函式一樣,過載運算子有乙個返回型別和乙個引數列表。如果我們定義的函式為類的成員函式 box operator const box 如果我們定義的函式為非成員函式,那麼我們需要為每次操作傳遞兩個...