在C++中提出了引用這個概念,它和指針類似,但用起來更方便。
一、普通引用
這裏的引用有時候也稱爲別名,實際就是說兩個不同名稱的標識符指向了同一個內存地址。
using namespace std;
int main()
{
int y;
int& r=y;
const int& q=12;
cout<<y<<" "<<r<<endl;
r++;
cout<<y<<" "<<r<<endl;
}
這裏有一個比較特別的地方,就是可以取常量的引用,但引用也必須設爲常量,這裏編譯器爲12分配了存儲單元,值被初始化爲12,q就是這個存儲單元的別名。
後面可以看到,r 增加後,y也增加了,說明它們指向的是同一塊地址。
使用引用時需要注意以下規則:
1) 當引用被創建時,它必須被初始化。
2)一旦一個引用被初始化指向一個對象,它就不能改變爲另一個對象的引用。
3)不可能有NULL的引用。必須確保引用是和一塊合法的存儲單元關聯。
二、函數中的引用
1.引用參數
引用常被用來做函數的參數,這個時候它的行爲就和指針一樣了,但語法更清晰。就是常說的按引用傳遞。
{
(*x)++;
}
void g(int& x)
{
x++;
}
int main()
{
int a=0;
f(&a);
g(a);
}
不過有時候這種傳遞參數的方法比較隱蔽,不知道傳的參數是否會被修改。
另外,如果要傳遞常量的話,就必須聲明函數參數爲常量引用:
void f(const int& a) {};
f(1);
2.指針引用
有時候我們需要傳遞的是指針的地址,在C語言裏我們通常是這樣:
void f(int**);
int i=4;
int* ip=&i;
f(&ip);
引用則可以有更簡單的語法
using namespace std;
void increment(int*& i) { i++ }
int main()
{
int* i=0;
cout<<"i= "<<i<<endl;
increment(i);
cout<<"i= "<<i<<endl;
}
3. 返回引用
有些用戶自定義的類型很大,如果按值返回開銷很大,這時採用按引用返回,就只返回地址,這樣比較快 捷。這個是在運算符重載中經常遇見的。但需要注意的是“不要返回臨時量,也就是局部變量”
{
public:
int x;
};
Widget& f(Widget& a)
{
a.x=10;
return a; //OK!
}
Widget& g()
{
Widget a;
return a; //返回臨時量 ,error
}
Widget& h()
{
static Widget a;
return a; //靜態 OK!
}
int main()
{
Widget a;
Widget b=f(a);
Widget c=h();
}
在C++裏面引用的運用是很靈活的,它最重要的地方就是在拷貝構造函數裏面。這個主題就下次再講了。