您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++中的引用傳遞有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++中的引用傳遞有哪些”吧!
C++中的引用傳遞
在C++中,參數傳遞是包含值傳遞的,且用法與C語言中一致,但是引用傳遞作為C++的一大特點,是C語言中未支持的
1. 引用變量的創建:
int rats; //創建引用變量rodents作為rats的別名 int & rodents = rats;使用引用變量的注意事項:
聲明時進行初始化
一旦與某個變量相關聯后,即僅效忠于此變量
對于上述第一條:
int rats; //不被允許的用法 int & rodents; rodents = rats;對于第二條,可參照如下例子:
#include < iostream > using namespace std; int main(void) { int rats = 10; int & rodents = rats; int bunnies = 20; cout << "after initialization:"<<endl; cout << "rats = " << rats << ", rodents = " << rodents << ", bunnies = "<<bunnies<< endl; rodents = bunnies; cout << "after assignment to rodents:" << endl; cout << "rats = "<<rats<<", rodents = " << rodents << ", bunnies = "<<bunnies<<endl; cout << "address of rats:"<< &rats<<endl; cout << "address of rodents:"<< &rodents<<endl; cout << "address of bunnies:"<< &bunnies<<endl; }輸出結果:
after initialization: rats = 10, rodents = 10, bunnies = 20 after assignment to rodents: rats = 20, rodents = 20, bunnies = 20 address of rats:0x7ffee795f4bc address of rodents:0x7ffee795f4bc address of bunnies:0x7ffee795f4ac針對第二條,這里還有一個例子:
#include < iostream > using namespace std; int main(void) { int rats = 10; int * pt = &rats; int & rodents = *pt; int bunnies = 20; cout << "after initialization:" << endl; cout << "rats = " << rats << ", rodents = " << rodents; cout << ", bunnies = "<<bunnies<<", *pt = "<< *pt<< endl; pt = &bunnies; cout << "after change of pt:"< <e ndl; cout << "rats = "<<r ats <<", rodents = "<< rodents; cout << ", bunnies = "<< bunnies <<", *pt = "<< *pt << endl; cout << "address of rats:" << &rats << endl; cout << "address of rodents:" << &rodents << endl; cout << "address of bunnies:" << &bunnies << endl; cout << "value in pt:" << pt << endl; }輸出結果:
after initialization: rats = 10, rodents = 10, bunnies = 20, *pt = 10 after change of pt: rats = 10, rodents = 10, bunnies = 20, *pt = 20 address of rats:0x7ffee11734bc address of rodents:0x7ffee11734bc address of bunnies:0x7ffee11734a4 value in pt:0x7ffee11734a4這里的
int & rodents = *pt
事實上是等效于int & rodents = rats
的。其實,我們可以將引用變量理解成
const
指針,它與引用非常接近,創建時必須初始化,且初始化后就不再改變指向的地址。int rats; int & rodents = rats; //可理解為,這里的*pr等效于rodents int * const pr = &rats;2. 用于參數傳遞的引用:
關于C++中的引用傳遞,與值傳遞之間的區別,這里借用 C++ Primer Plus 中的例子來說明:
#include < iostream > void swapr(int &a,int &b); // a,b are aliases for ints void swapp(int *p,int* q); // p,q are addresses of ints void swapv(int a,int b); // a,b are new variables int main( ) { using namespace std; int wallet1 = 300; int wallet2 = 350; cout << "wallet1 = $" << wallet1; cout <<" wallet2 = $" << wallet2 << endl; cout << "Using references to swap contents:\n"; swapr(wallet1,wallet2); // pass variables cout << "wallet1 = $" << wallet1; cout <<" wallet2 = $" << wallet2 << endl; cout << "Using pointers to swap contents again:\n"; swapp(&wallet1,&wallet2); // pass addresses of variables cout << "wallet1 = $"<< wallet1; cout <<" wallet2 = $" << wallet2 << endl; cout << "Trying to use passing by value:\n"; swapv(wallet1,wallet2); // pass values of variables cout << "wallet1 = $" << wallet1; cout <<" wallet2= $" << wallet2 << endl; return 0; } void swapr(int & a,int & b) // use references { int temp; temp = a; // use a,b for values of variables a = b; b = temp; } void swapp(int * p, int * q) // use pointers { int temp; // use *p,*q for values of variables temp = *p; *p = *q; *q = temp; } void swapv(int a, int b) // trying use values { int temp; temp = a; a = b; b = temp; }輸出結果:
wallet1 = $300 wallet2 = $350 Using references to swap contents: wallet1 = $350 wallet2 = $300 Using pointers to swap contents again: wallet1 = $300 wallet2 = $350 Trying to use passing by value: wallet1 = $300 wallet2= $350原始
wallet1
和wallet2
經過引用參數傳遞和指針參數傳遞,均可成功達到交換的目的,但是僅通過簡單的按值傳遞卻沒有達到效果。這里不在討論指針參數傳遞與值傳遞的關系,可參考參數傳遞(一)。在引用參數傳遞中,聲明
void swapr(int & a,int & b)
,調用形式參數a
和b
分別初始化為wallet1
和wallet2
,即在swapr
中a
和b
為wallet1
和wallet2
的別名。3.引用參數與const:
這里將對引用參數傳遞與值傳遞中的一些特殊情況作一些說明。
借用如下代碼:
#include < iostream > double cube(double a); double refcube(const double &ra); int main () { using namespace std; double x = 3.0; int y = 10; cout << "case double x:" <<endl; cout << "x = " << x << ", cube(x) = " << cube(x); cout << ", refcube(x) = " << refcube(x) << endl; cout << "case x + 3.0:" <<endl; cout << "x + 3.0 = " << x + 3.0 << ", cube(x + 3.0) = " << cube(x + 3.0); cout << ", refcube(x + 3.0) = " << refcube(x + 3.0) << endl; cout << "case int y:" <<endl; cout << "y = " << y << ", cube(y) = " << cube(y); cout << ", refcube(y) = " << refcube(y) << endl; } double cube(double a) { return a * a * a; } double refcube(const double &ra) { return ra * ra * ra; }輸出結果:
case double x: x = 3, cube(x) = 27, refcube(x) = 27 case x + 3.0: x + 3.0 = 6, cube(x + 3.0) = 216, refcube(x + 3.0) = 216 case int y: y = 10, cube(y) = 1000, refcube(y) = 1000這里有三種情況,第一種為正常情況,傳入
double x
,cube
和refcube
均能接受,但是對于后面兩種情況,雖然均輸出正確,但是這里確實多了一些東西double refcube(
const
double &ra)
。
對于
x + 3.0
來說,它實際上是一個右值(一個標識臨時性對象的表達式,或者是一個不與任何對象相聯系的值———參考 數據結構與算法分析.C++語言描述 第四版 ),若使用double refcube(double &ra)
,編譯器會報錯candidate function not viable: expects an l-value for 1st argument
,即傳遞參數應為左值(可被引用的數據對象,例如變量、數組元素、結構成員、引用和解除引用的指針———參考 C++ Primer Plus 第6版 ),這里傳入參數與左值不匹配,那么加入const
后會發生什么呢,它促使會生成一個臨時變量,用來儲存傳入的右值x + 3.0
,并參與計算。對于
int y
來說,若使用double refcube(double &ra)
,編譯器會報錯candidate function not viable: no known conversion from 'int' to 'double &' for 1st argument
,即傳入的參數類型不正確,此時加入const
,這時也會生成臨時變量,轉換為正確的類型后進行計算。總結上述兩點,使用引用傳遞在加入
const
后會在如下兩種情況下,創建臨時變量協助特殊情況下的參數傳遞:
實參的類型正確,但不是左值。
實參的類型不正確,但可以轉換為正確的類型。
這里還有幾點注意事項:
在上述兩種情況下,編譯器都會生成一個臨時匿名變量,將傳入的參數的值傳給該臨時匿名變量(值傳遞),并讓引用(如上述
ra
)指向它,這些臨時變量只在函數調用期存在,此后編譯器便可以隨意將其刪除。在一些早期要求較為寬松的C++編譯器中,對于第二種情況,當發生類型錯誤后,即使不使用
const
,也會將錯誤類型的值傳給創建的臨時匿名變量,以實現類型轉換,那么當涉及到傳入參數的改變時就會出現問題,如,定義long a = 3, b = 5;
和void swapr(int & a, int & b)
,在swap(a, b)
后,便會發現結果并未有變化,那么這時就體現出了使用const
的好處,因為如果加入const
,在引用指向臨時匿名變量時,就將引用聲明為不可變類型,從而直接阻止了傳入參數的改變,也就避免了這一錯誤的發生。而較新版本的C++編譯器為了避免上述情況,便規定在不使用
const
的情況下,就不會創建臨時匿名變量。
感謝各位的閱讀,以上就是“C++中的引用傳遞有哪些”的內容了,經過本文的學習后,相信大家對C++中的引用傳遞有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。