赞
踩
C++中传值参数和引用参数怎样区别呢?
看以下例子:
#include<iostream>
using namespace std;
void swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
}
main()
{
int a=3,b=5;
cout<< "before ‘swap’:a="<<a<<",b="<<b<<endl;
swap(a,b);
cout<<"after ‘swap’:a="<<a<<",b="<<b<<endl;
}
这个例子是传值调用, 意思就是 形参 的 改变不会影响 实参的值。
你运行一下可知 主函数调用了swap函数后 a,b的值并没有发生交换。
原因是,调用swap函数时 编译器为 swap(int a,int b) 中的形参 a , b单独分配内存空间,并接受主函数传递来的值,这块内存空间和 main()函数中的 a ,b 不是同一内存空间。 所以在swap(int a,int b) 中 a , b发生了交换,但main函数中a , b没发生交换。即主调函数与被调函数的操作对象各不相同,参数仅在调用时由实参向形参传递,而不可由形参向实参传递。
要使a ,b发生交换 需要使用传址调用。程序改为如下:
#include<iostream>
using namespace std;
void swap(int & a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
cout<<"in ‘swap’:a="<<a<<",b="<<b<<endl;
}
main()
{
int a=3,b=5;
cout<< "before ‘swap’:a="<<a<<",b="<<b<<endl;
swap(a,b);
cout<<"after ‘swap’:a="<<a<<",b="<<b<<endl;
}
引用可以看作是一个变量的别名,使用 引用 时 ,对于void swap(int a,int b) 编译器并没有给形参a,b分配新的内存空间,只是使形参a,b指向了main函数中实参a,b的内存空间,他们共享同一内空间,即把地址给了形参。所以在void swap(int a,int b)函数中对这块内存的改变也就改变了实参的值。
除了使用引用,也可以使用指针。
指针方式和引用方式都属于传址调用。那么指针和引用又有什么样的区别呢?
两种参数都允许函数修改实参所对应的对象,两种类型的参数都允许有效得向函数传递大型类对象。
两者在参数传递过程中,有如下几点不同
(1)引用必须被初始化为指向一个对象,一旦初始化了,它就不能在指向其它对象。指针可以指向一系列不同的对象,当然也可以定义为NULL;
如:
calss Type{ void operation(const Type&p1,const Type&p2); int main(){ Tyoe obj1; Type obj2 = operation(obj1,0); //引用参数的实参不能为0 } |
所以在函数中,一个参数可能指向不同的对象的情况,或者这个参数可能不指向任何对象,则必须实用指针参数。
(2)引用参数的一个重要用法,它允许我们在有效实现重载操作符的还能保证用法的直观性。如下例:
Matrix operator+(Matrix m1,Matrix m2) { Matrix result; //do computation return result; } |
通过上面实现后,就能够支持两个Matrix对象的加法,如:a+b
但是这样做,效率会非常低。因为该实现的实参是按值传递,两个Matrix对象相加的时候,内容被拷贝到operator+()函数的参数区中,因为Matrix对象非常大的时候,分配这样一个对象,并把它拷贝到函数参数区中的时间和空间开销比较高。
而为了提高我们的操作符函数的效率,假定我们决定把参数申明为指针的时候,如下:
Matrix operator+(Matrix *m1,Matrix *m2) { Matrix result; //do computation return result; } |
这种做法,在一定程度上很好得解决了函数实现的效率问题,但是带来一个新的问题是用户的使用习惯,对于这样的operator+操作,调用方式变为:&a+&b,这样大大颠覆了我们传统的调用方式。
所以这时候,如果申明为引用的方式,就能到达到效率和使用习惯的目的:
Matrix operator+(Matrix &m1,Matrix &m2) { Matrix result; //do computation return result; } |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。