C++学习-探究一下引用

Ubuntu 18.04 gcc 4.8.4

什么是引用

在代码层面简单的理解就是变量的别名,简单的讲我们可以通过以下方式声明一个引用:

int val = 10;
int& val_ref = a;

但是,如果这样引用

int &a = 10;

这样会报错,因为u对于左值引用来说,需要右边的临时变量可以取地址,而对于常量10来说时无法取地址的。
与这个概念经常被一起提及的便是指针,那么这两者究竟有什么关系呢?

引用的作用

无论是指针还是引用,其两者有一个重要的作用:减少值拷贝。回忆以下我们在学习c/c++的时候,在定义函数会存在的三种传递方式:值传递、指针传递、引用传递。三者中值传递会发生值拷贝影响程序的运行效率,此外在处理函数返回值的时候也可能会发生值拷贝。设想一下这种情况:当我们需要传递或者返回一个很大很复杂的数据结构的时候,值拷贝的存在是十分消耗资源的。

引用占用内存吗?

从表面意思上说,引用是变量的别名,可能我们就认为其不占用内存,而你进行计算几个引用的大小时,返回的是其变量的大小,那么其究竟是否占用内存呢? 我们通过代码探究一下:

#include "iostream"
class RefTest {
 public:
  RefTest(double val = 4.0) : val_ref_(val) {}

 private:
  double &val_ref_;
};

int main() {
  std::cout << sizeof(RefTest) << std::endl;
}

输出:

> 8

这里我们通过一个只包含引用的类来进行测试,最后输出的结果为8,我的测试环境是在64位系统,这不是正好一个指针的大小吗?说到这里想必你也已经明白了。

指针和引用底层实现

其实,通过引用和指针的汇编结果来说,其两者本质上都是一样的,都是一个地址。或许我们可以这样理解,从语言层面上讲引用可以理解为一个const指针;从底层的汇编机器码来说两者都是一个地址。

指针和引用的区别

  • 指针是可以独立存在的; 但是引用不行
  • 引用必须要进行初始化,指针没有必要
  • 指针可以设置为NULL, 但是引用不行
  • 引用一旦进行初始化之后,不会再改变其指向;但指针可以

左值引用和右值引用

大多数情况下,我们默认的引用就是左值引用,但是在C++ 11中添加了右值引用的概念。那么两者之间有什么区分吗?

  • 可以取地址的,有名字的,非临时的就是左值;
  • 不能取地址的,没有名字的,临时的就是右值;
    可见立即数,函数返回的值等都是右值;而非匿名对象(包括变量),函数返回的引用,const对象等都是左值。

C++ 11中提供了std::move函数, 将一个左值引用转换成一个右值引用。但是需要注意两点:

  • 如果你想要让一个对象能被move,就不要把这个对象声明为const。在const对象上的move请求会被默认地转换成拷贝操作。
  • std::move事实上没有move任何东西,它甚至不能保证它转换出来的对象能有资格被move。你唯一能知道的事情就是,把std::move用在一个对象之后,它变成了一个右值。

REF

https://zhuanlan.zhihu.com/p/282846275
https://zhuanlan.zhihu.com/p/89175296
https://zhuanlan.zhihu.com/p/97128024

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值