2.5. References2.5. 引用A reference serves as an alternative name for an object. In real-world programs, references are primarily used as formal parameters to functions. We'll have more to say about reference parameters in Section 7.2.2 (p. 232). In this section we introduce and illustrate the use of references as independent objects. 引用就是对象的另一个名字。在实际程序中,引用主要用作函数的形式参数。我们将在第 7.2.2 节 再详细介绍引用参数。在这一节,我们用独立的对象来介绍并举例说明引用的用法。 A reference is a compound type that is defined by preceding a variable name by the & symbol. A compound type is a type that is defined in terms of another type. In the case of references, each reference type "refers to" some other type. We cannot define a reference to a reference type, but can make a reference to any other data type. 引用是一种复合类型,通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。在引用的情况下,每一种引用类型都“关联到”某一其他类型。不能定义引用类型的引用,但可以定义任何其他类型的引用。 A reference must be initialized using an object of the same type as the reference: 引用必须用与该引用同类型的对象初始化: 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 A Reference Is an Alias引用是别名Because a reference is just another name for the object to which it is bound, all operations on a reference are actually operations on the underlying object to which the reference is bound: 因为引用只是它绑定的对象的另一名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上: refVal += 2; adds 2 to ival, the object referred to by refVal. Similarly, 将 refVal 指向的对象 ival 加 2。类似地, int ii = refVal; assigns to ii the value currently associated with ival. 把和 ival 相关联的值赋给 ii。
The important concept to understand is that a reference is just another name for an object. Effectively, we can access ival either through its actual name or through its alias, refVal. Assignment is just another operation, so that when we write 要理解的重要概念是引用只是对象的另一名字。事实上,我们可以通过 ival 的原名访问 ival,也可以通过它的别名 refVal 访问。赋值只是另外一种操作,因此我们编写 refVal = 5; the effect is to change the value of ival to 5. A consequence of this rule is that you must initialize a reference when you define it; initialization is the only way to say to which object a reference refers. 的效果是把 ival 的值修改为5。这一规则的结果是必须在定义引用时进行初始化。初始化是指明引用指向哪个对象的唯一方法。 Defining Multiple References定义多个引用We can define multiple references in a single type definition. Each identifier that is a reference must be preceded by the & symbol: 可以在一个类型定义行中定义多个引用。必须在每个引用标识符前添加“&”符号: 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 const Referencesconst 引用A const reference is a reference that may refer to a const object: const 引用是指向 const 对象的引用: const int ival = 1024; const int &refVal = ival; // ok: both reference and object are const int &ref2 = ival; // error: non const reference to a const object We can read from but not write to refVal. Thus, any assignment to refVal is illegal. This restriction should make sense: We cannot assign directly to ival and so it should not be possible to use refVal to change ival. 可以读取但不能修改 refVal ,因此,任何对 refVal 的赋值都是不合法的。这个限制有其意义:不能直接对 ival 赋值,因此不能通过使用 refVal 来修改 ival。 For the same reason, the initialization of ref2 by ival is an error: ref2 is a plain, nonconst reference and so could be used to change the value of the object to which ref2 refers. Assigning to ival through ref2 would result in changing the value of a const object. To prevent such changes, it is illegal to bind a plain reference to a const object. 同理,用 ival 初始化 ref2 也是不合法的:ref2 是普通的非 const 引用,因此可以用来修改 ref2 指向的对象的值。通过 ref2 对 ival 赋值会导致修改 const 对象的值。为阻止这样的修改,需要规定将普通的引用绑定到 const 对象是不合法的。
A const reference can be initialized to an object of a different type or to an rvalue (Section 2.3.1, p. 45), such as a literal constant: const 引用可以初始化为不同类型的对象或者初始化为右值(第 2.3.1 节),如字面值常量: int i = 42; // legal for const references only const int &r = 42; const int &r2 = r + i; The same initializations are not legal for nonconst references. Rather, they result in compile-time errors. The reason is subtle and warrants an explanation. 同样的初始化对于非 const 引用却是不合法的,而且会导致编译时错误。其原因非常微妙,值得解释一下。 This behavior is easiest to understand when we look at what happens when we bind a reference to an object of a different type. If we write 观察将引用绑定到不同的类型时所发生的事情,最容易理解上述行为。假如我们编写 double dval = 3.14; const int &ri = dval; the compiler transforms this code into something like this: 编译器会把这些代码转换成如以下形式的编码: int temp = dval; // create temporary int from the double const int &ri = temp; // bind ri to that temporary If ri were not const, then we could assign a new value to ri. Doing so would not change dval but would instead change temp. To the programmer expecting that assignments to ri would change dval, it would appear that the change did not work. Allowing only const references to be bound to values requiring temporaries avoids the problem entirely because a const reference is read-only. 如果 ri 不是 const,那么可以给 ri 赋一新值。这样做不会修改 dval,而是修改了 temp。期望对 ri 的赋值会修改 dval 的程序员会发现 dval 并没有被修改。仅允许 const 引用绑定到需要临时使用的值完全避免了这个问题,因为 const 引用是只读的。
A const reference may be bound to an object of a different but related type or to an rvalue. const 引用则可以绑定到不同但相关的类型的对象或绑定到右值。 ![]() |