博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中的引用详解
阅读量:6540 次
发布时间:2019-06-24

本文共 2907 字,大约阅读时间需要 9 分钟。

1.引用的本质 

   

   在 C/C++中,变量仅能且只能通过两种方式被访问、传递或获取。即:

        通过值 访问 / 传递变量

        通过地址 访问 / 传递变量 – 这种方法就是指针

 
   
引用常被认为是变量的别名,实际上 C++ 中根本就没有什么叫做别名的定义。引用变量也就是个指针变量,它也拥有内存空间。最关键的是引用是一种会被编译器自动解引用的指针。引用本质上被编译成指针常量(constant pointers)。这意味着:
int &i = j  --->   int *const i = &j 

引用的常见例子

#include 
int 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 
int main(){ int i = 10; int *const j = &i; int *const k = &*j; int *const l = &*k; cout<
<<","<<*j<<","<<*k<<","<<*l<
 

 
     其中j,k.l的
value
都是i的地址

3.引用占据内存

#include 
class Test{ int &i; // int *const i; int &j; // int *const j; int &k; // int *const k; };int main(){ cout<<"size of class Test = "<
     
   C++标准并没有解释编译器如何实现引用的行为。所以实现取决于编译器,而大多数情况下就是将其实现为一个const指针。因此引用仍然占据内存。

4.引用支持虚函数机制

#include 
class 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.

转载于:https://www.cnblogs.com/engineerLF/p/5393072.html

你可能感兴趣的文章
cocos2d-x CCTextureCache
查看>>
Eclipse中tomcat启动时提示java.lang.ClassNotFoundException: XXX class
查看>>
10项可用性结论与指南
查看>>
linux EXT4格式分区扩容
查看>>
MyPython-->进阶篇-->测试代码
查看>>
Docker容器安装
查看>>
attr和prop的区别 chosen插件
查看>>
Linux入门学习教程:虚拟机体验之KVM篇
查看>>
天池大数据周冠军分享|附移动推荐算法赛答辩会Top5选手PPT
查看>>
HDU 2870 Largest Submatrix
查看>>
HTML5 图片缩放功能
查看>>
VirtualBox 4.2 released !
查看>>
Windows线程同步API
查看>>
内存调试技巧
查看>>
工作日志-2014年11月
查看>>
计算机网络起源 网络发展简介(一)
查看>>
IOS响应者链
查看>>
概率相关问题
查看>>
在IIS上运行node
查看>>
NSNumber(把数字存进数组字典等的问题)
查看>>