C++ 语言左值引用 (lvalue reference)

C++11 中新增了右值引用 (rvalue reference)。当我们使用术语引用 (reference) 时,指的其实是左值引用 (lvalue reference)。

引用 (reference) 为对象起了另外一个名字,引用类型引用 (refers to) 另外一种类型。通过将声明符写成 &d 的形式来定义引用类型,其中 d 是声明的变量名。引用变量是一个别名,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>int main()
{int ival = 2048;/* refval1 指向 ival,它是 ival 的另一个名字。 */int &refval1 = ival;/* 报错:引用必须被初始化。 */int &refval2;return 0;
}
1>d:\visual_studio_workspace\...\yongqiang.cpp(20): error C2530: 'refval2': references must be initialized

一般在初始化变量时,初始值会被拷贝到新建的对象中。定义引用时,程序把引用和它的初始值绑定 (bind) 在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。引用必须在声明时将其初始化,不能先声明后赋值。

1. 引用即别名

引用并非对象,它只是为一个已经存在的对象所起的另外一个名字。定义了一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>int main()
{int ival = 2048;/* refval1 指向 ival,它是 ival 的另一个名字。 */int &refval1 = ival;/* 把 2 赋给了 refval1 指向的对象,即是赋给了 ival。 */refval1 = 2;/* 与 yq = ival 执行结果一样。 */int yq = refval1;return 0;
}

为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。以引用作为初始值,实际上是以与引用绑定的对象作为初始值。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>int main()
{int ival = 2048;/* refval1 指向 ival,它是 ival 的另一个名字。 */int &refval1 = ival;/* 把 2 赋给了 refval1 指向的对象,即是赋给了 ival。 */refval1 = 2;/* 与 yq = ival 执行结果一样,yq 被初始化为 ival 的值。 */int yq = refval1;/* refval2 绑定到了那个与 refval1 绑定的对象上,这里就是绑定到 ival。 */int &refval2 = refval1;return 0;
}

因为引用本身不是一个对象,所以不能定义引用的引用。变量名称是变量附属在内存位置中的标签,引用是变量附属在内存位置中的第二个标签。可以通过原始变量名称或引用来访问变量的内容。

2. 引用的定义

允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号 & 开头。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>int main()
{/* i1 和 i2 都是 int。 */int i1 = 1024, i2 = 2048;/* ref1 是一个引用,与 i1 绑定,ref2 是 int。 */int &ref1 = i1, ref2 = i2;/* i3 是 int,ref3 是一个引用,与 i3 绑定。 */int i3 = 4096, &ref3 = i3;/* ref4 和 ref5 都是引用。 */int &ref4 = i3, &ref5 = i2;return 0;
}

引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>int main()
{/* 错误:引用类型的初始值必须是一个对象。 */int &refval1 = 10;double dval = 3.1415926;/* 错误:此处引用类型的初始值必须是 int 对象。 */int &refval2 = dval;return 0;
}
1>d:\visual_studio_workspace\...\yongqiang.cpp(14): error C2440: 'initializing': cannot convert from 'int' to 'int &'
1>d:\visual_studio_workspace\...\yongqiang.cpp(19): error C2440: 'initializing': cannot convert from 'double' to 'int &'

不存在空引用,引用必须连接到一块合法的内存。一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。引用必须在创建时被初始化,指针可以在任何时间被初始化。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif#include <iostream>int main()
{double d;double &refd = d;d = 12.34;std::cout << "Value of d : " << d << std::endl;std::cout << "Value of d reference : " << refd << std::endl;std::cout << "Address of d : " << &d << std::endl;std::cout << "Address of d reference : " << &refd << std::endl;double yq = 67.89;double cyq = yq;yq = 99.99;std::cout << "Value of yq : " << yq << std::endl;std::cout << "Value of cyq : " << cyq << std::endl;std::cout << "Address of yq : " << &yq << std::endl;std::cout << "Address of cyq : " << &cyq << std::endl;return 0;
}
Value of d : 12.34
Value of d reference : 12.34
Address of d : 00CFF7EC
Address of d reference : 00CFF7EC
Value of yq : 99.99
Value of cyq : 67.89
Address of yq : 00CFF7D0
Address of cyq : 00CFF7C0
请按任意键继续. . .

3. yongqiang

 double d = 12.34;double &refd = d;

引用可理解为 const 指针,必须在创建时进行初始化,一旦引用和某个变量关联起来,该引用就会一直指向该变量。

 double d = 12.34;double * const refd= &d;

数组的引用要表明数组的大小。

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif#include <iostream>int main()
{int ai[] = { 1,2,3,4 };int(&ref)[4] = ai;std::cout << ref << std::endl;std::cout << ref[0] << std::endl;std::cout << ref[1] << std::endl;std::cout << ref[2] << std::endl;std::cout << ref[3] << std::endl;return 0;
}
00D3FC5C
1
2
3
4
请按任意键继续. . .

References

(美) Stanley B. Lippman, (美) Josée Lajoie, (美) Barbara E. Moo 著, 王刚, 杨巨峰 译. C++ Primer 中文版[M]. 第 5 版. 电子工业出版社, 2013.
https://www.informit.com/store/c-plus-plus-primer-9780321714114
https://www.runoob.com/

C++ 语言左值引用 (lvalue reference)相关推荐

  1. C++/C++11中左值、左值引用、右值、右值引用的使用

    C++的表达式要不然是右值(rvalue),要不然就是左值(lvalue).这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能. 在C++语言中,二者的区别就没 ...

  2. 左值右值,左值引用和右值引用及其用途

    目录 1.左值和右值 2.引用 (1)左值引用 (2)右值引用 3.左值引用的用途 (1)作为复杂名称变量的别名 (2)用于rangeFor循环 (3)避免复制大的对象 (4)参与函数中的参数传递 4 ...

  3. 的引用_左值、右值、左值引用、右值引用

    [导读]:本文主要详细介绍了左值.右值.左值引用.右值引用以及move.完美转发. 左值和右值 左值(left-values),缩写:lvalues 右值(right-values),缩写:rvalu ...

  4. 喵喵喵?喵嘞个咪?---- C++左值引用

    编译环境:VS 2013 文章目录 一.C 语言传参 1. 传值 2. 传址 二.引用 1. 引用的概念 2. 引用的特性 3. const 的引用 4. 数组引用 5. 引用的使用场景 6. 引用和 ...

  5. [c++]-c++中的左值和右值、左值引用和右值引用、万能引用和引用折叠及完美转发

    1.左值和右值 1.1左值和右值定义 在c++中,左值是一个指向内存的东西,换句话来讲,左值有地址,保存在内存中,右值则为不指向任何地方东西,即不在内存中占有确定位置.一般来说,右值是暂时和短暂的,而 ...

  6. std::move 左值右值 左值引用右值引用

    参考:https://blog.csdn.net/daaikuaichuan/article/details/88371948 https://zhuanlan.zhihu.com/p/9458820 ...

  7. 左值、右值、左值引用、右值引用

    1. 左值 左值(lvalue,left value),顾名思义就是赋值符号左边的值,可以取地址.准确来说,左值是表达式(不一定是赋值表达式)后依然存在的持久对象. 可以将左值看作是一个关联了名称的内 ...

  8. C++11 右值引用与常量左值引用保存临时变量(函数返回值)的底层分析

    右值引用保存临时变量(函数返回值)的问题 :临时变量是右值 1.普通变量接收函数返回值: 2.右值引用变量接收函数返回值: 3.用const int& 和右值引用是一样的效果,只是const ...

  9. 【C++11】左值引用和右值引用

    目录 一.新的类功能 1.新的默认成员函数 2.类成员变量初始化 3.强制生成默认函数的关键字default 4.禁止生成默认函数的关键字delete 二.左值和右值 1.左值和左值引用 2.右值和右 ...

最新文章

  1. python就业方向有哪些-目前Python这么火,Python有哪些就业方向?
  2. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )
  3. Dubbo架构设计详解
  4. san-hot-loader 应用及原理实现
  5. 牛腩新闻发布系统——初探CSS
  6. hbase shell中命令无法删除?
  7. cisco 交换机vlan-trunk的配置详解及应用实例:
  8. tfs 未能在以下位置创建报表文件夹 /TfsReports: 授予的权限不足,无法执行此操作
  9. 面对SDN/NFV部署挑战 网络厂商能做什么?
  10. 【学习笔记】结合代码理解设计模式 —— 代理模式(静态代理、动态代理、延伸)
  11. 【全观测系列】Elasticsearch应用性能监控实践
  12. java组件是什么意思_年前面试京东3面凉经~ 面试过程与真题全分享+备战春招(java)...
  13. 【操作系统】页置换算法
  14. 将之前写完的猜数字游戏改为通过javabean_【沃德英语】好玩的单词游戏
  15. [技术文档]Linux从入门到精通
  16. HCNA认证课程—VRP基础操作总结
  17. 理解分布函数(概率论)
  18. 【路径规划】遗传算法求解考虑分配次序的多无人机协同目标分配问题
  19. 不适合学习编程的人是你吗?
  20. 毫米和像素怎么换算_将mm换算为px (毫米换算为像素)

热门文章

  1. Go Web Chapter2-Form汇总
  2. Linux Mint 13开启Compiz Fusion特效(3D桌面 屏幕火焰等)
  3. win11屏幕自动变暗的解决办法
  4. 矩阵中零空间,行空间的意义
  5. 常用统计算法JAVA实现 - 方差与标准差(05)
  6. 数据仓库—数据仓库—NCR Teradata Warehouse 介绍
  7. linux 编译 cflags,如何设置CFLAGS和LDFLAGS来编译pycryp
  8. iOS开发——开发者官网注册新设备
  9. 第一章 Linux操作系统概述
  10. 第四课 文字编排机技巧