首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

引用reference用作对象的另一名字。在实际程序中,引用主要用作函数的形式参数。我们将在7.2.2节再详细介绍引用参数。在这一节,我们用独立的对象来介绍并举例说明引用的用法。

引用是一种复合类型compound type,通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。在引用的情况下,每一种引用类型都“关联到”某一其他类型。不能定义引用类型的引用,但可以定义任何其他类型的引用。

引用必须用和该引用同类型的对象初始化:

int ival = 1024;

int &refVal = ival; // ok: refVal refers to ival

int &refVal2;       // error: a reference must be initialized

int &refVal3 = 10; // error: initializer must be an object

1. 引用是别名

因为引用只是它绑定的对象的另一名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上:

refVal += 2;

refVal指向的对象ival2。类似地,

int ii = refVal;

把和ival相关联的值赋给ii

当引用初始化后,只要该引用存在,它就保持绑定到初始化时指向的对象。不可能将引用绑定到另一个对象。

要理解的重要概念是引用只是对象的另一名字。事实上,我们可以通过ival的原名访问ival,也可以通过它的别名refVal访问。赋值只是另外一种操作,因此当我们编写

refVal = 5;

效果是把ival的值修改为5。这一规则的结果是必须在定义引用时进行初始化。初始化是指明引用指向哪个对象的唯一方法。

2. 定义多个引用

可以在一个类型定义行中定义多个引用。必须在每个引用标识符前添加“&”符号:

int i = 1024, i2 = 2048;

int &r = i, r2 = i2;      // r is a reference, r2 is an int

int i3 = 1024, &ri = i3; // defines one object, and one reference

int &r3 = i3, &r4 = i2;  // defines two references

3. const引用

const引用是指向const对象的引用:

const int ival = 1024;

const int &refVal = ival;  // ok: both reference and object are const

int &ref2 = ival;            // error: nonconst reference to a const object

可以读取但不能修改refVal,因此,任何对refVal的赋值都是不合法的。这个限制有其意义:不能直接对ival赋值,因此不能通过使用refVal来修改ival

同理,用ival初始化ref2也是不合法的:ref2是普通的const引用nonconst reference),因此可以用来修改ref2指向的对象的值。通过ref2ival赋值会导致修改const对象的值。为阻止这样的修改,须要规定将普通的引用绑定到const对象是不合法的。

术语:const引用是指向const的引用

C++程序员常常随意地使用术语const引用。严格来说,“const引用”的意思是“指向const对象的引用”。类似地,程序员使用术语“非const引用”表示指向非const类型的引用。这种用法非常普遍,我们在本书中也遵循这种用法。

const引用可以初始化为不同类型的对象或者初始化为右值(2.3.1节),如字面值常量:

int i = 42;

//  legal for const references only

const int &r = 42;

const int &r2 = r + i;

同样的初始化对于非const引用却是不合法的,而且会导致编译时错误。其原因非常微妙,值得解释一下。

观察将引用绑定到不同的类型时所发生的事情,最容易理解上述行为。假如我们编写

double dval = 3.14;

const int &ri = dval;

编译器会把这些代码转换成如以下形式的编码:

int temp = dval;          // create temporary int from the double

const int &ri = temp;    // bind ri to that temporary

如果ri不是const,那么可以给ri赋一新值。这样做不会修改dval,而是修改了temp。期望对ri的赋值会修改dval的程序员会发现dval并没有被修改。仅允许const引用绑定到需要临时使用的值完全避免了这个问题,因为const引用是只读的。

习题                                                              

习题2.24  下列哪些定义是非法的?为什么?如何改正?

   (a) int ival = 1.01;    (b) int &rval1 = 1.01;

   (c) int &rval2 = ival;  (d) const int &rval3 = 1;

习题2.25  下列给出的定义中,哪些赋值是非法的?如果赋值合法,解释赋值的作用。

   (a) rval2 = 3.14159;         (b) rval2 = rval3;

   (c) ival = rval3;            (d) rval3 = ival;

习题2.26  (a)中的定义和(b)中的赋值存在哪些不同?哪些是非法的?

   (a) int ival = 0;          (b) ival = ri;

         const int &ri = 0;         ri = ival;

习题2.27  下列代码输出什么

   int i, &ri = i;

   i = 5; ri =10;

   std::cout << i << " " << ri << std::endl;

const引用只能绑定到与该引用同类型的对象。

const引用则可以绑定到不同但相关的类型的对象或绑定到左值。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论