找回密码
 立即注册

QQ登录

只需一步,快速开始

工控课堂 首页 工控文库 上位机编程 查看内容

C++的引用

2022-6-27 22:02| 发布者: gk-auto| 查看: 420| 评论: 0

摘要: 引用:reference已存在变量的别名。使用引用的必要性:资源使用思想层:受限制的指针。语法层:T a; T p=a;编译器:给你做了保证,一定是经过初始化的指针汇编层:和指针一样。在汇编层,指针和引用是完全一样的。引 ...

引用:reference
已存在变量的别名。

使用引用的必要性:资源使用

思想层:受限制的指针。
语法层:T a; T &p=a;
编译器:给你做了保证,一定是经过初始化的指针
汇编层:和指针一样。

在汇编层,指针和引用是完全一样的。
引用是一个语法糖,T a; T &p=a; 等价于 T *const p = &a

    int x=0;
00676664  mov         dword ptr [x],0  
    int &a = x;
0067666B  lea         eax,[x]  
0067666E  mov         dword ptr [a],eax  
    a = 1;
00676671  mov         eax,dword ptr [a]  
00676674  mov         dword ptr [eax],1  
    int *p = &x;
0067667A  lea         eax,[x]  
0067667D  mov         dword ptr [p],eax  
    *p = 2;
00676680  mov         eax,dword ptr [p]  
00676683  mov         dword ptr [eax],2  

    int *const p2 = &x;
00676689  lea         eax,[x]  
0067668C  mov         dword ptr [p2],eax  
    *p2 = 3;
0067668F  mov         eax,dword ptr [p2]  
00676692  mov         dword ptr [eax],3 

引用的情况:

int a = 1;
const int b = 1;
int &ref1 = a;
int &ref2 = 1;//ERROR
const int &ref3 = b;
const int &ref4 = 1;

Q:唯独int &ref2 = 1;//ERROR?
A:C++的早期这种语法是被允许的,但是在函数调用传参数时,会给程序员带来误解,于是后面就禁止了这种语法。

引用规则的特例:const引用

void f(int &i){}
void f(const int &i){}

int main(){
    int i = 1;
    f(i);//call f(int &i)
    f(2);//call f(const int &i)
    return 0;
}
void f(int &i){}
//void f(const int &i){}

int main(){
    int i = 1;
    f(i);//call f(int &i)
    f(2);//ERROR
    return 0;
}
//void f(int &i){}
void f(const int &i){}

int main(){
    int i = 1;
    f(i);//call f(const int &i)
    f(2);//call f(const int &i)
    return 0;
}

C++语言中就有了新的参数传递方式:引用传递 void f(T &p) 。实质也是传值。

自定义类型最好用引用传递,可以避免不必要的构造函数和析构函数的调用。
内置类型建议用值传递,自定义类型建议用引用传递,内置类型,值传递会比按引用传递更高效。

解释见:这里

利用引用交换两个数字

#include <iostream>
#include <stdlib.h>
using namespace std;
void swap(int &a, int &b){
    int tmp = a;
    a = b;
    b = tmp;
}
int main(){
    int a = 3;
    int b = 4;
    swap(a, b);
    cout << "a=" << a<<" " << "b=" << b << endl;
    return 0;
}

引用的级数
只能一级,引用的对象必须是一个已存在的地址。引用变量本身的地址,外界不能访问。
References are not objects; they do not necessarily occupy storage,
Because references are not objects, there are no arrays of references, no pointers to references, and no references to references。
int& a[3]; // ERROR
int&* p; // ERROR
int& &r; // ERROR

引用和指针叠加
int a; int *p = &a; int *&r = p; //OK

使用引用的场景:

  • 给函数传递可变参数
  • 给函数传递大型对象
  • 引用函数返回值;

Q:引用能实现的基本上指针都可以实现,那为什么C++还需要引入引用呢?
A:最初主要是为了支持运算符重载。
c = a + b是可以接受的写法,而c = &a + &b 就不是很方便而且有歧义了。
写法上的方便是要第一考虑的。

Q:C++引入了引用,那为什么C++不和Java一样让指针对使用者不可见呢?
A:历史原因。为了兼容C语言。程序员是自由的。

Q:C++为什么选择&作为引用的标识符?
A:需要用一个符号告诉编译器,传的是引用。&在C语言中是取地址的作用,于是就选择了它。

Q:this为什么是指针类型,而不是引用类型?
A:历史原因。this诞生早于引用。某种意义上来讲,this应该被设计为引用类型。

Q:Why is "this" not a reference?
A:Because "this" was introduced into C++ (really into C with Classes) before references were added. Also, I chose "this" to follow Simula usage, rather than the (later) Smalltalk use of "self".

Q:拷贝构造函数参数一定是引用,不然编译通不过,为什么?
A:因为在入参的过程中,如果不是引用,会首先进行一次值拷贝;而要实现的就是拷贝构造,就会造成不断的递归最后爆炸。

Q:引用是受限制的指针,哪里受限制了?
A:引用变量本身的地址外界不可获得,当然编译器是可以的。

Q:引用变量是否占有内存空间?
A:引用可以不占用,也可以占有。语法规定对引用变量的操作都是对被引用对象的操作。

struct S {
    int a;
    int &b;
};
int x = 123;
S s(123,x);

sizeof(S)=?//32位环境等于8

non-const引用的汇编视角
image

const引用的汇编视角
image

说明:const引用变量绑定没有地址的对象时,会生成一个临时变量/匿名对象来中转。

上一篇:C的指针下一篇:C++的构造
关注公众号,加入500人微信群,下载100G免费资料!

最新评论

热门文章
关闭

站长推荐上一条 /1 下一条

QQ|手机版|免责声明|本站介绍|工控课堂 ( 沪ICP备20008691号-1 )

GMT+8, 2025-12-23 00:30 , Processed in 0.086222 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

返回顶部