C++中的引用传递有哪些

这篇文章主要讲解了“C++中的引用传递有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中的引用传递有哪些”吧!

10年积累的网站设计制作、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站制作后付款的网站建设流程,更有阜南免费网站建设让你可以放心的选择与我们合作。

C++中的引用传递

在C++中,参数传递是包含值传递的,且用法与C语言中一致,但是引用传递作为C++的一大特点,是C语言中未支持的

1. 引用变量的创建:
int rats;
//创建引用变量rodents作为rats的别名
int & rodents = rats;
 
使用引用变量的注意事项:
  1. 声明时进行初始化

  2. 一旦与某个变量相关联后,即仅效忠于此变量

对于上述第一条:

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:"< 
  

输出结果:

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 = "< 
  

输出结果:

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
 

原始wallet1wallet2经过引用参数传递和指针参数传递,均可成功达到交换的目的,但是仅通过简单的按值传递却没有达到效果。这里不在讨论指针参数传递与值传递的关系,可参考参数传递(一)。

在引用参数传递中,声明void swapr(int & a,int & b),调用形式参数ab分别初始化为wallet1wallet2,即在swaprabwallet1wallet2的别名。

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:" < 
  

输出结果:

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均能接受,但是对于后面两种情况,虽然均输出正确,但是这里确实多了一些东西double refcube(constdouble &ra)

  1. 对于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,并参与计算。

  2. 对于int y来说,若使用double refcube(double &ra),编译器会报错candidate function not viable: no known conversion from 'int' to 'double &' for 1st argument即传入的参数类型不正确,此时加入const,这时也会生成临时变量,转换为正确的类型后进行计算。

C++中的引用传递有哪些

总结上述两点,使用引用传递在加入const后会在如下两种情况下,创建临时变量协助特殊情况下的参数传递:

  1. 实参的类型正确,但不是左值。

  2. 实参的类型不正确,但可以转换为正确的类型。

这里还有几点注意事项:

  1. 在上述两种情况下,编译器都会生成一个临时匿名变量,将传入的参数的值传给该临时匿名变量(值传递),并让引用(如上述ra)指向它,这些临时变量只在函数调用期存在,此后编译器便可以随意将其删除。

  2. 在一些早期要求较为宽松的C++编译器中,对于第二种情况,当发生类型错误后,即使不使用const,也会将错误类型的值传给创建的临时匿名变量,以实现类型转换,那么当涉及到传入参数的改变时就会出现问题,如,定义long a = 3, b = 5;void swapr(int & a, int & b),在swap(a, b)后,便会发现结果并未有变化,那么这时就体现出了使用const的好处,因为如果加入const,在引用指向临时匿名变量时,就将引用声明为不可变类型,从而直接阻止了传入参数的改变,也就避免了这一错误的发生。

  3. 而较新版本的C++编译器为了避免上述情况,便规定在不使用const的情况下,就不会创建临时匿名变量。

感谢各位的阅读,以上就是“C++中的引用传递有哪些”的内容了,经过本文的学习后,相信大家对C++中的引用传递有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


网页名称:C++中的引用传递有哪些
本文网址:http://ybzwz.com/article/jpsshj.html