而C++語言中可以對變數取另一個別名。這一個功能稱為參照(reference),例如使用參照對變數num取newnum這一樣一個別名,就會如下所示
int num;
int &newnum = num;
製作別名時,不管是原變數名還是別名,都可以做相同的存取。只要變更任何一方的值,另一方也會跟著改變。
newnum = 13;
cout << "num = " << num << endl;
cout << "newnum = " << newnum << endl;
注意最後一行,存取newnum時,不需要&
在C語言中使用指標,也可以得到同樣的效果。但指標在進行存取時,必需要對所指的資料加上*,因此比較複雜。
int num;
int *newnum = #
*newnum = 400;
而參照使用的地方最主要是「對函數的引數使用」
像下列一樣宣告引數時,使用參照可以對函數傳值
double Addnum(double &a, double &b)
{
return a + b;
}
但是,這樣其實跟平常的call by value感覺好像差不多,以下就建立一個我覺得最有用的地方。
void caculate(double a, double b, double &sum, double &sub)
{
sum = a + b;
sub = a - b;
}
而我們這樣使用此函數
double first = 6;
double second = 4;
double ans1,ans2;
caculate(first,second,ans1,ans2);
printf("ans1 is %lg\nans2 is %lg\n",ans1,ans2);
注意到沒?
在之前若我們要由副程式傳回兩個結果,我們通常必需在副程式中建立一個陣列,
並且傳回那一個陣列的指標,
但是,若透過參照的話,就簡單很多了。
其實,參照就像「肥仔魚」這一個變數,我們另外把它的名字取作「阿肥」、「阿仔」、「阿魚」,其實,這是個都是同一個東西,我們對其中一個做改變,那麼當讀取任何一個值時,都會是改變過時候的值。
有一點類似指標啦,只不過在使用的時候更加便利,不需要加*哩
這裡另外提到把參照加上const的形式
int x;
const int &y = x;
x = 100; // ok
y = 200; // error
由x去改值沒有問題,但若由y去改值會出現錯誤
這裡有一個程式
...
struct Person
{
char name[50];
int age;
};
void PrintPersonRef(Person &psn); // 傳參照
void PrintPersonPtr(Person *psn); // 傳址
void PrintPersonVal(Person psn); // 傳值
int main()
{
PrintPersonRef(shain1); // 不加&
PrintPersonPtr(&shain1); // 加&
PrintPersonVal(shain1); // 不加&
...
}
看到這裡就會浮現一個問題
因為傳參照與傳值函數的呼叫方法相同,會導致不知道要不要變更引數的值
為了避免這一個問題,在函數中要變更引數的值時,使用「傳址」比較好
若沒有要變更引數的話,利用const 加上參照速度會比傳值還要快
這樣比較方便以後程式的維護
整理如下:
不變更引數+小型資料=傳值
不變更引數+結構體等大資料=執行const後的傳參照值
變更引數+小型資料=傳址
變更引數+結構體等大資料=傳址
[2008.9.5]補充
回傳值為reference
例:
const QWMatrix & QCanvasView::inverseWorldMatrix () const
參考資料:博碩文化-新C++學習繪本
沒有留言:
張貼留言