1.引用的本质
在 C/C++中,变量仅能且只能通过两种方式被访问、传递或获取。即:
⑴通过值 访问 / 传递变量
⑵通过地址 访问 / 传递变量 – 这种方法就是指针
引用的常见例子:
#includeint main(){ int i = 10; int &j = i; int* const k=&i; j++; cout<<<<*k<
为什么打印相同的地址?引用变量时会被编译器自动解引用,诸如"cout << &j << endl;"的语句,编译器就会将其转化成语句"cout << &*j << endl"。
这样来理解。如前描叙,j实际为指针常量,即int *const j= &i。所以语句"cout << &i << &j<< endl"变为"cout << &i << &*j<< endl"也就是"cout << &i << j<< endl"。所以打印相同的地址。
2.引用的级联(cascading)
看下面的代码:
#include不依赖编译器的自动替换功能,手动进行替换也能达到相同的目标。上面的代码等同于:int main(){ int i = 10; // A Simple Integer variable int &j = i; // A Reference to the variable int &k = j; // A reference to a reference variable int &l = k; // A reference to a reference to a reference variable. cout< <<","< <<","< <<","< <
#include其中j,k.l的 value 都是i的地址int main(){ int i = 10; int *const j = &i; int *const k = &*j; int *const l = &*k; cout< <<","<<*j<<","<<*k<<","<<*l<
3.引用占据内存
#includeC++标准并没有解释编译器如何实现引用的行为。所以实现取决于编译器,而大多数情况下就是将其实现为一个const指针。因此引用仍然占据内存。class Test{ int &i; // int *const i; int &j; // int *const j; int &k; // int *const k; };int main(){ cout<<"size of class Test = "<
4.引用支持虚函数机制
#includeclass A{public: virtual void print() { cout<<"A.."<
引用支持虚函数机制,而虚函数的动态信息只有通过指针实现。更加说明引用其实就是一个const指针。
5.数组引用和常量引用
❶数组引用
#include"iostream"using namespace std;void display(const int a[],int length){ int i=0; while(i
❷常量引用
#include"iostream"using namespace std;int _tmain(int argc, _TCHAR* argv[]){ int a = 30; const int &b = 30; cout <<"a= " << a << "\tb= " << b << endl;//30 30 a = 40; cout << "a= " << a << "\tb= " << b << endl;//30 40 return 0;}❸对于指针也有对应的引用。
6.引用作为形参和返回类型
Person old;
Person new=old;
在JAVA中,使用引用传递,修改old则new值也变化。C++中除数组外,默认为值传递,即隐式的调用了Person类的默认拷贝构造函数。C++中同类型的对象赋值基本为值传递。
❶引用做为形参,能够避免拷贝时间,提高效率。但是不能传递局部变量给上一级引用变量。如:
Person test(Person &p){ .......return p;}Person &pNew=test(p);//报错
因为return p到 =test(P)过程中间,程序调用了默认拷贝函数,生成了一个test函数局部域的临时Person对象,而临时变量在test函数结束的时候销毁了。因为引用类型变量时必须初始化为一个已经定义并且有效的对象,所以调用失败了。
❷引用也可以作为传递类型,这时候复制不会调用拷贝构造函数:
Person& test(Person &p){ ....... return p;}Person &pNew=test(p);//不调用拷贝函数Person pNew=test(p);//调用拷贝构造函数
7.总结
C++标准规定,引用可以占内存也可以不占,取决于编译器实现。
❶占内存的实现就是使用指针了。很多编译器为了简单都全部采用这种实现方法。
❷不占内存的实现,是引用和引用的对象在同一个函数中的时候。局部变量名其实是一个相对于栈基址的偏移量,这种情况下你定义这个局部变量的引用,编译器可以直接给这个引用赋同样的偏移值,这样引用名和变量名完全没有区别。这就是别名的含义了。
❸引用为形参只有用指针实现这种方法。例如换值函数swap,以下两种定义等同:
void swap(int const* a,int const * b ) void swap(int&a, int&b)
参考:
1.
2.