学习了参数的三种传递方式:值传递、指针传递与引用传递后不由地对这不熟悉的引用感到好奇,根据引用的概念,引用在定义初始化时与对象名绑定,为对象建立引用名,就类似于别名的作用,可别名不就会像值传递一样不改变实参的值了吗,可引用传递又能跟指针传递一样改变实参的值,我便抱着这种疑问对引用展开探究。
先看下引用传递的效果
#include <iostream>
using namespace std;
void test(int, int&);
void main() {
int a = 10;
int b = 20;
test(a, b);
cout << a<< "\012" << b << endl;
}
void test(int c,int &d) {
c = 15;
d = 25;
}
如果引用只是别名,那他就应该不会占用内存而是跟对象共享内存,反之则更类似于指针,所以先测试引用的内存关系。
void main() {
double a ;
double &b =a;
double *p =&a;
double *q =&b;
cout <<"p:" << p << endl;
cout <<"q:" << q << endl;
cout <<sizeof(a) << endl;
cout <<sizeof(b) << endl;
cout <<sizeof(p) << endl;
}
从结果可以看出引用跟对象地址相同,因此大小也相同,即引用不同于指针,引用不会申请内存,那么多个引用应该也是对象的多重别名。
double a;
double &b = a;
double &c = a;
double &d = a;
double *p = &a;
double *q = &b;
double *r = &c;
double *s = &d;
cout << "p:" << p<< endl;
cout << "q:" << q<< endl;
cout << "r:" << r<< endl;
cout << "s:" << s << endl;
而间接赋值有三个必要条件:
1、实参形参。
2、实参传地址给形参。
3、形参通过地址间接地去修改实参的值。
按照引用的规则来看就是通过引用修改实参的值,套入赋值条件则可以理解为实参传地址给形参,形参通过引用的形式接收地址,在修改值时对形参的地址进行间址操作,而这就跟指针的传递相同,而引用初始化时必须赋值与不得修改引用对象的特点可以看出引用同常指针相同。
void test(int*, int&);
void main() {
int a;
int &b = a;
test(&a, b);
}
void test(int * const c,int &d) {
*c =15;
cout<< *c <<endl;
d =25;
cout << *c <<endl;
}
可以看作引用在编译过程中以常指针作为实现方式,c++引入可读性与实用性更强的引用,在可以代替指针时应避免使用指针。
另外引用传递时并非不占内存,查阅资料得知由于其实现方式同常指针,所以引用占用的空间大小与指针相同,而通过sizeof方法得出的只是对象的大小,而这些都是c++为了实用性作出的细节隐藏。