溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C++中的引用傳遞有哪些

發(fā)布時(shí)間:2021-10-13 11:00:38 來源:億速云 閱讀:193 作者:iii 欄目:編程語言

這篇文章主要講解了“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):
  1. 聲明時(shí)進(jìn)行初始化

  2. 一旦與某個(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
 

原始wallet1wallet2經(jīng)過引用參數(shù)傳遞和指針參數(shù)傳遞,均可成功達(dá)到交換的目的,但是僅通過簡單的按值傳遞卻沒有達(dá)到效果。這里不在討論指針參數(shù)傳遞與值傳遞的關(guān)系,可參考參數(shù)傳遞(一)。

在引用參數(shù)傳遞中,聲明void swapr(int & a,int & b),調(diào)用形式參數(shù)ab分別初始化為wallet1wallet2,即在swaprabwallet1wallet2的別名。

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 xcuberefcube均能接受,但是對于后面兩種情況,雖然均輸出正確,但是這里確實(shí)多了一些東西double refcube(constdouble &ra)。

  1. 對于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ì)算。

  2. 對于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ì)算。

C++中的引用傳遞有哪些

總結(jié)上述兩點(diǎn),使用引用傳遞在加入const后會在如下兩種情況下,創(chuàng)建臨時(shí)變量協(xié)助特殊情況下的參數(shù)傳遞:

  1. 實(shí)參的類型正確,但不是左值。

  2. 實(shí)參的類型不正確,但可以轉(zhuǎn)換為正確的類型。

這里還有幾點(diǎn)注意事項(xiàng):

  1. 在上述兩種情況下,編譯器都會生成一個(gè)臨時(shí)匿名變量,將傳入的參數(shù)的值傳給該臨時(shí)匿名變量(值傳遞),并讓引用(如上述ra)指向它,這些臨時(shí)變量只在函數(shù)調(diào)用期存在,此后編譯器便可以隨意將其刪除。

  2. 在一些早期要求較為寬松的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ā)生。

  3. 而較新版本的C++編譯器為了避免上述情況,便規(guī)定在不使用const的情況下,就不會創(chuàng)建臨時(shí)匿名變量。

感謝各位的閱讀,以上就是“C++中的引用傳遞有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C++中的引用傳遞有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(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)容。

c++
AI