本文參考 : C++ Primer (第四版) 7.2.4及 16.1.5 相關章節
GeekBand 侯捷老師,學習筆記
開發環境采用:VS2013版本
關鍵問題一、傳遞引用與傳指針、傳值的區別?
值傳遞 (pass by value),指針傳遞(pass by pointer),當發生函數調用時,需要給形參分配存儲單元、當傳遞是對象時,要調用拷貝構造函數。
而且指針最后析構時,要處理內存釋放問題。
引用傳遞(pass by refenrence),在內存中沒有產生形參。效率大大提高!也不用處理指針的析構問題。
通過以上分析,我們設計程序時應該盡量使用引用,少利用指針。如果非得強調類似,”值傳遞,如”char 類型只有一個字節,請君左轉,屏幕右上角有個紅叉“
關鍵問題二:如何傳遞引用
那么,傳遞不了指針,我們傳遞數組怎么樣?首先看下下面的簡易代碼:(C++ Primer 7.2.4)
#include "stdafx.h" #include<iostream> using namespace std; void PrintValues(const int ia[10]) { for (int i = 0; i != 10; i++) { cout << ia[i] << endl; } } int _tmain(int argc, _TCHAR* argv[]) { int j[2] = { 0, 1 }; PrintValues(j); return 0; }

這里因為編譯器忽略了為任何數組形參指定長度,所以會造成數組內存越界問題。
而且,數組有二個特性,影響作用在數組上的函數:一是不能復制數組,二是使用數組名時, 數組名會自動指向其第一個元素的指針。因為不能復制,所以無法編寫使用數組類型的形參,數組會自動轉化為指針。
我們驗證下,將Void PrintValues(const int ia[10])改為 Void PrintValues(const int *ia),結果與上圖一致,這里就不貼了。
那么怎么解決這個問題呢?
方案一:顯示傳遞表示數組大小的形參
#include "stdafx.h"
#include<iostream>
using namespace std;
void PrintValues(const int *ia,int size)
{
for (int i = 0; i != size; i++)
{
cout << ia[i] << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int j[] = { 0, 1 };
PrintValues(j,sizeof(j)/sizeof(*j));
return 0;
}

此方法雖然可以解決問題,但並不是我們需要的,這部分代碼看不出來區別,但工程龐大后,使用引用要比指針高效,所以我們還是要利用引用的特性來解決這個問題。
將數組形參可聲明為數組的引用,如果形參是數組的引用,編譯器會傳遞數組的引用本身
我們再修改下代碼:如下
#include "stdafx.h"
#include<iostream>
using namespace std;
void PrintValues( int (&ia)[2])
{
for (int i = 0; i != 2; i++)
{
cout << ia[i] << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int j[2] = { 0, 1 };
PrintValues(j);
return 0;
}

結果顯示,與pass by pointer方法結果一致,但是這里有一個缺陷,這里面 int (&ia)[2],編譯器要檢查數組實參和形參的大小。擴展性太差!
最終采用非類型模板解決這個問題,代碼如下:
#include "stdafx.h" #include<iostream> using namespace std; template<class T,int N> void PrintValues( T (&ia)[N]) { for (int i = 0; i != N; i++) { cout << ia[i] << endl; } } int _tmain(int argc, _TCHAR* argv[]) { int j[2] = { 0, 1 }; PrintValues(j); return 0; }
結果如圖:

通過以上分析, 可以采用非類型模板形參傳遞中來解決效率問題。
