C++中的鏈式操作
代碼編譯環境: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++中的鏈式操作