您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++中的引用傳遞有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++中的引用傳遞有哪些”吧!
C++中的引用傳遞
在C++中,參數(shù)傳遞是包含值傳遞的,且用法與C語言中一致,但是引用傳遞作為C++的一大特點(diǎn),是C語言中未支持的
1. 引用變量的創(chuàng)建:
int rats; //創(chuàng)建引用變量rodents作為rats的別名 int & rodents = rats;使用引用變量的注意事項(xiàng):
聲明時(shí)進(jìn)行初始化
一旦與某個(gè)變量相關(guān)聯(lián)后,即僅效忠于此變量
對于上述第一條:
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; }輸出結(jié)果:
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針對第二條,這里還有一個(gè)例子:
#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; }輸出結(jié)果:
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
事實(shí)上是等效于int & rodents = rats
的。其實(shí),我們可以將引用變量理解成
const
指針,它與引用非常接近,創(chuàng)建時(shí)必須初始化,且初始化后就不再改變指向的地址。int rats; int & rodents = rats; //可理解為,這里的*pr等效于rodents int * const pr = &rats;2. 用于參數(shù)傳遞的引用:
關(guān)于C++中的引用傳遞,與值傳遞之間的區(qū)別,這里借用 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; }輸出結(jié)果:
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
經(jīng)過引用參數(shù)傳遞和指針參數(shù)傳遞,均可成功達(dá)到交換的目的,但是僅通過簡單的按值傳遞卻沒有達(dá)到效果。這里不在討論指針參數(shù)傳遞與值傳遞的關(guān)系,可參考參數(shù)傳遞(一)。在引用參數(shù)傳遞中,聲明
void swapr(int & a,int & b)
,調(diào)用形式參數(shù)a
和b
分別初始化為wallet1
和wallet2
,即在swapr
中a
和b
為wallet1
和wallet2
的別名。3.引用參數(shù)與const:
這里將對引用參數(shù)傳遞與值傳遞中的一些特殊情況作一些說明。
借用如下代碼:
#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; }輸出結(jié)果:
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
均能接受,但是對于后面兩種情況,雖然均輸出正確,但是這里確實(shí)多了一些東西double refcube(
const
double &ra)
。
對于
x + 3.0
來說,它實(shí)際上是一個(gè)右值(一個(gè)標(biāo)識臨時(shí)性對象的表達(dá)式,或者是一個(gè)不與任何對象相聯(lián)系的值———參考 數(shù)據(jù)結(jié)構(gòu)與算法分析.C++語言描述 第四版 ),若使用double refcube(double &ra)
,編譯器會報(bào)錯(cuò)candidate function not viable: expects an l-value for 1st argument
,即傳遞參數(shù)應(yīng)為左值(可被引用的數(shù)據(jù)對象,例如變量、數(shù)組元素、結(jié)構(gòu)成員、引用和解除引用的指針———參考 C++ Primer Plus 第6版 ),這里傳入?yún)?shù)與左值不匹配,那么加入const
后會發(fā)生什么呢,它促使會生成一個(gè)臨時(shí)變量,用來儲存?zhèn)魅氲挠抑?code>x + 3.0,并參與計(jì)算。對于
int y
來說,若使用double refcube(double &ra)
,編譯器會報(bào)錯(cuò)candidate function not viable: no known conversion from 'int' to 'double &' for 1st argument
,即傳入的參數(shù)類型不正確,此時(shí)加入const
,這時(shí)也會生成臨時(shí)變量,轉(zhuǎn)換為正確的類型后進(jìn)行計(jì)算。總結(jié)上述兩點(diǎn),使用引用傳遞在加入
const
后會在如下兩種情況下,創(chuàng)建臨時(shí)變量協(xié)助特殊情況下的參數(shù)傳遞:
實(shí)參的類型正確,但不是左值。
實(shí)參的類型不正確,但可以轉(zhuǎn)換為正確的類型。
這里還有幾點(diǎn)注意事項(xiàng):
在上述兩種情況下,編譯器都會生成一個(gè)臨時(shí)匿名變量,將傳入的參數(shù)的值傳給該臨時(shí)匿名變量(值傳遞),并讓引用(如上述
ra
)指向它,這些臨時(shí)變量只在函數(shù)調(diào)用期存在,此后編譯器便可以隨意將其刪除。在一些早期要求較為寬松的C++編譯器中,對于第二種情況,當(dāng)發(fā)生類型錯(cuò)誤后,即使不使用
const
,也會將錯(cuò)誤類型的值傳給創(chuàng)建的臨時(shí)匿名變量,以實(shí)現(xiàn)類型轉(zhuǎn)換,那么當(dāng)涉及到傳入?yún)?shù)的改變時(shí)就會出現(xiàn)問題,如,定義long a = 3, b = 5;
和void swapr(int & a, int & b)
,在swap(a, b)
后,便會發(fā)現(xiàn)結(jié)果并未有變化,那么這時(shí)就體現(xiàn)出了使用const
的好處,因?yàn)槿绻尤?code>const,在引用指向臨時(shí)匿名變量時(shí),就將引用聲明為不可變類型,從而直接阻止了傳入?yún)?shù)的改變,也就避免了這一錯(cuò)誤的發(fā)生。而較新版本的C++編譯器為了避免上述情況,便規(guī)定在不使用
const
的情況下,就不會創(chuàng)建臨時(shí)匿名變量。
感謝各位的閱讀,以上就是“C++中的引用傳遞有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C++中的引用傳遞有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。