1. 程式人生 > >C++中的鏈式操作

C++中的鏈式操作

getch sna 產生 fun pen 教程 輸入輸出 data 圖片

代碼編譯環境:Windows7 32bits+VS2012。


1.什麽是鏈式操作

鏈式操作是利用運算符進行的連續運算(操作)。它的特點是在一條語句中出現兩個或者兩個以上相同的操作符,如連續的賦值操作、連續的輸入操作、連續的輸出操作、連續的相加操作等都是鏈式操作的樣例。

鏈式操一定涉及到結合律的問題。比如鏈式操作賦值操作滿足右結合律,即a=b=c被解釋成a=(b=c)。而鏈式輸出操作原則滿足左結合律,即cout<<a<<b被解釋成(cout<<a)<<b,基本數據類型的鏈式操作都有明白的定義。而涉及到類類型的鏈式操作則往往須要進行對應操作符的重載。

2.類的鏈式操作

為了實現類的鏈式操作,使鏈式操作可以進行,操作符的重載必須滿足一定的要求:
(1)操作符重載函數一定不能返回void類型。


由於void類型不能參與不論什麽運算,所以,操作符重載函數返回void類型實際上是阻止了鏈式操作的可能性。

(2)對賦值操作符進行重載,假設返回的是類的對象。那麽鏈式賦值操作必須借助於拷貝構造函數才幹進行。

這樣不懂那會有較大的執行開銷,還要編寫正確的拷貝構造函數。

考察以下的程序。

#include <iostream>
using namespace std;

class Complex{
    double real;
    double
image; public: Complex(double r=0.0,double i=0.0){ real=r; image=i; } Complex(const Complex& c){ cout<<"Copy Constructor"<<endl; real=c.real; image=c.image; } void Show(){ cout<<real<<"+"<<image<<"i"
<<endl; } Complex operator=(const Complex&); }; Complex Complex::operator=(const Complex& c) { real=c.real; image=c.image; return *this; } int main(int argc,char* argv[]) { Complex c1(2.3,4.5),c2,c3; c1.Show(); c3=c2=c1; c2.Show(); c3.Show(); getchar(); }

程序的執行結果是:
技術分享

可以看到,在連續的兩次賦值操作過程中,一共兩次調用拷貝構造函數。第一次發生在執行c2=c1的操作中。函數的返回值(暫時對象)是由c1構造的,這時發生了一次拷貝構造函數的調用;第二次發生在為c3賦值的時候,賦值運算的返回值仍然是一個Complex類的對象。這時又發生了一次拷貝構造函數的調用。

讓賦值操作依賴於拷貝構造函數,顯然不是一種明智的做法。

思考:Complex& Complex::operator=(Complex& c){…},會有什麽結果?

只將賦值運算符重載函數的申明和定義改動例如以下:

Complex& operator=(const Complex&);
Complex& Complex::operator=(const Complex& c)
{
    real=c.real;
    image=c.image;
    return *this;
}

相同是上面的程序,輸出結果為:
技術分享

也就是說,一次拷貝構造函數都沒有調用。原因是賦值操作符函數返回Complex類的引用。不用產生一個新的暫時對象,這樣大大提高了程序執行效率。所以。賦值運算符重載差點兒無一例外地返回引用。


3.實現輸入輸出的鏈式操作

輸入操作符(>>)和輸出操作符(>>)的重載函數必須返回引用,否則鏈式無法操作無法完畢。

一般來說,實現輸入操作符重載,一律採用例如以下函數原型:

istream& operator>>(istream&, className&);

而實現輸出操作符重載,一律採用例如以下函數原型:

ostream& operator<<(ostream&, className&);

假設操作符函數的返回的是istream或ostream類的對象。而不是引用,會出現編譯錯誤。出錯的原因以及關於輸入輸入操作符的重載,敬請期待我的興許blog。


參考文獻

[1] ]陳剛.C++高級進階教程[M].武漢:武漢大學出版社。2008.

C++中的鏈式操作