這個寫的很不錯 http://www.cnblogs.com/Mr-xu/archive/2012/08/07/2626973.html 什麼叫引用? 引用就是對某對象的另一個名字。 主要用途: 為了描述函數的參數和返回值,特別是運算符的重載。 用法: X var; X& r = var; 那麼r是 ...
這個寫的很不錯
http://www.cnblogs.com/Mr-xu/archive/2012/08/07/2626973.html
什麼叫引用?
引用就是對某對象的另一個名字。
主要用途:
為了描述函數的參數和返回值,特別是運算符的重載。
用法:
X var;
X& r = var;
那麼r是對象var的一個引用,而&在此處是作為引用的標識符而不是區地址。
特點:
(1)引用在創建的時候必須進行初始化,以確保引用會指向某個對象。
int i = 1;
int& r1 = i; //正確:r1被初始化
int& r2; //錯誤:r2沒有被初始化
extern int& r3; //正確:r3在別處被初始化了
(2)所有對引用的操作,都可以看成是對被引用的對象執行的。
void g()
{
int ii = 0;
int& rr = ii;
rr++; //實際上是執行了ii++
int* pp = &rr; //pp指向了ii
}
因此在對應用進行操作時完全可以把引用替換為被引用的對象。
(3)一個引用的值在初始化之後就不可能改變了,它總是引用它初始化所指的那個對象,至死不渝。
(4)可以通過&r來獲取r所指對象的地址。
(5)引用本身並不占有存儲單元,有時候編譯器可以通過優化去掉引用,使得在執行時根本不存在任何表示引用的東西。
(6)對於T&這種引用,屬於變數引用,被引用的類型必須是T的左值,而對於const T&是常量引用,的初始式不必是一個左值,甚至可以不是類型T的,此時:
[1]首先需要將該類型到T類型進行隱式轉換;
[2]隨後將結果存入一個類型為T的臨時變數;
[3]最後將這個臨時變數作為初始式的值。
double& dr = 1; //錯誤,要求左值
const double& cdr = 1; //正確
對於初始化的解釋是
double temp = double(1); //首先建立一個具有正確值的臨時變數
const double& cdr = temp; //用臨時變數作為cdr的初始值
這種保存引用初始式的臨時變數將會一直存在,直到這個引用的作用域結束。
(7)需要區分對變數的引用和對常量的引用,常量引用是不能通過引用對目標變數進行修改的,從而使被引用的目標稱為const,達到一定的安全性。
string foo();
void bar(string& s);
那麼下列的表達式將是非法的:
bar(foo());
bar(“hello world”);
因為foo()和”hello world”串都會產生一個臨時對象,而在C++中,這些臨時對象都是const類型,上面表達式試圖將const類型對象轉為非congst類型對象,是非法的。
(8)可以通過引用來描述一個函數參數,使該函數能夠改變傳進來的該參數的值。
void increment(int& aa) { aa++; }
void f()
{
int x = 1;
increment(x); //x = 2
}
為了提高程式的可讀性,應該避免讓函數去修改它們的參數。相反應該讓函數明確地返回一個值,或者明確要求一個指針參數:
int next(int p) { return p+1; }
void incr(int* p) { (*p)++; }
void g()
{
int x = 1;
increment(x); //x = 2
x = next(x); //x = 3
incr(&x); //x = 4
}
將引用作為參數傳遞進去將會,使得人們強烈感受到參數將被修改。
(9)引用還可以用於定義一些函數,使它們既可以被用於賦值的左邊也可以用於右邊。
(10)不能給數組建立引用,因為數組是若幹元素組成的集合。
引用作為返回值
引用作為返回值需要在函數名前加&
引用作為返回值最大的好處就是記憶體中不產生被返回值的副本。
#include <iostream.h>
float temp;
float fn1(float r);
float &fn2(float r);
float fn1(float r)
{
temp = (float)(r*r*3.14);
return = temp;
}
flaot& fn2(float r)
{
temp = (float)(r*r*3.14);
return temp;
}
void main()
{
float a = fn1(10.0);
float &b = fn1(10.0);
float c = fn2(10.0);
float &d = fn2(10.0);
cout << a << c << d;
}
不能返回局部變數的引用,主要是因為局部變數會在函數返回後被銷毀,因此被返回的引用就成了無所指的引用,使程式進入未知狀態。
不能返回函數內部new分配的記憶體引用,雖然不存在被動銷毀的問題,對於這種情況(返回函數內部new分配記憶體的使用),又面臨其他尷尬局面,例如函數返回的引用只是作為一個臨時變數出現,而沒有被賦予一個時間的變數,那麼這個引用所指向的空間就無法釋放,造成memory leak。
可以返回類成員的引用,但最好是const,主要是當對象的屬性與某種業務關聯時,其賦值常常與某些其他的屬性或者對象的狀態有關,如果獲得了非常量的引用則會導致單純賦值破壞業務規則的完整性。
引用與一些操作符重載,這還是與引用可以作為左值有關。
引用和多態