引用和指標參數,這兩種參數都允許函數修改實參,也都允許有效地向函數傳遞大型類對象。那麼,怎麼樣決定把函數參數聲明成引用還是指標呢?
引用必須被初始化為指向一個對象,而且一旦初始化了,就不能指向其他對象。而指標可以指向一系列不同的對象也可以什麼都不指向。
因為指標可能指向一個對象或者沒有任何對象,所以函數在確定指標實際指向一個有效地對象之前不能安全地解引用一個指標。例如:
class X;void manip(X *px){//在解引用之前確定它非0if(px != 0)//解引用指標}
另一方面,對於引用參數,函數不需要保證它指向一個對象。例如:
class Type{};void operate(const Type& p1,const Type& p2);int main(){Type obj1;//錯誤:引用參數的實參不能為0Type obj2 = operate(obj1,0);}
如果一個參數可能在函數中指向不同的對象,或者這個參數可能不指向任何對象,則必須使用指標參數。
引用參數的一個重要用法是,它允許我們在有效實現重載操作符的同事,還能保證用法的直觀性。
看個執行個體,它使用了Matrix類類型。我們想支援兩個Matrix對象的加法和賦值操作符,使他們的用法同內建類型一樣“自然”:
Matrix a,b,c;c = a + b;
Matrix類對象的加法和賦值操作符用重載操作符來實現。
為重載操作符提供一個定義:
Matrix operator+(Matrix m1,Matrix x2){Matrix result;//do the computation in resultreturn result;}
實參按值傳遞,效率很低。
為提高效率,假設我們將參數聲明為指標。operator+()新的實現代碼:
Matrix operator+(Matrix *m1,Matrix *x2){Matrix result;//do the computation in resultreturn result;}
這樣有一個缺點:失去了加法操作符用法的直觀性。現在指標參數要求我們傳遞地址作為實參,指向Matrix對象。現在,我們的加法操作必須如下編程:
&a + &b;
但是這樣比較難看,介面不友好。而且,在一個複合運算式中加三個對象變得很困難:
//這無法工作//&a+&b的傳回型別是Matrix對象&a + &b + &c;
程式必須這樣寫:
&(&a + &b) + &c;
但是,引用參數提供了我們需要的方案。此時函數接收到的是實參的左值而不是值得拷貝。引用參數的實參是Matrix對象本身,這允許我們像對內建資料類型的對象一樣自然地使用加法操作符。
operator+()實現代碼:
Matrix operator+(Matrix &m1,Matrix &x2){Matrix result;//do the computation in resultreturn result;}
它支援如下形式的Matrix對象的加法:
a + b + c;