1

我在一些不错的 C++ 教程中读到,确实存在独立引用,并且行为类似于别名。但是...我想知道它是做什么用的。为什么要使用别名。

此外,一些我不清楚的代码:

int a;
int &ref = a; // independent reference
int b = 19;
ref = b;  
cout << a << " " << ref << "\n";
ref--;  
cout << a << " " << ref << "\n";

首先, ref 是对 a 的“引用”。我从第二行代码中了解到 ref 的地址(因此是ampershead)是a。然后,整数 ref 被赋予 b (19) 的值。第一个 cout 返回 a 和 ref,都等于 19。为什么?整数a不是ref的地址吗?然后,递减 ref,最后一个 cout 给出两次 18. a 和递减的 ref。

神秘的唯一可能的奇怪解释:这里 int& 本身就是一个类型,“对整数的独立引用”,这种类型意味着别名。那么无论你对 ref 做什么,对 a 也是如此。

那正确吗?但是为什么需要别名呢?

4

6 回答 6

3

那么无论你对 ref 做什么,对 a 也是如此。

这是一种非常准确的看待它的方式。本质上,两者都refa代相同的int

为什么需要别名?

引用的一种非常常见的用途是将参数传递给函数。考虑以下:

void f(const HugeStruct& data) {
 ...
}

这允许调用者以HugeStruct比使用指针时更便宜且语法更好的方式将 a 传递给调用者。

于 2012-05-19T16:47:01.197 回答
3

你是对的。引用在许多方面类似于const指针(例如,修改引用的值会修改原始值),并且您不能将引用绑定到除其初始变量之外的任何其他内容,但它不能null,并且使用它的语法也不同(无需取消引用 ( *, ->))。因为它不是指针,所以最好的描述是alias:将其视为同一变量的不同名称。

此外,如果您将引用作为函数参数传递,则不会复制该变量(例如使用指针和它指向的值),并且对引用的任何更改都会反映在原始变量上。

对于 const 引用也有一些特殊规则,允许临时值超出其常规生命周期,直到它绑定的 const 引用超出范围。

于 2012-05-19T16:48:14.877 回答
2

在您的示例中没有多大意义。但是考虑一下:

int & ri = expensive_function_call(args)->some_map[calculate_the_key()].first;
if (ri > 6) ri = 6;

对比

if (expensive_function_call(args)->some_map[calculate_the_key()].first > 6)
    expensive_function_call(args)->some_map[calculate_the_key()].first = 6;

当然,您可以使用指针:

int * pi = &expensive_function_call(args)->some_map[calculate_the_key()].first;
if (*pi > 6) *pi = 6;

通过使用别名(引用或指针),不仅代码几乎减半,而且程序在运行时必须完成的工作也减半(至少在编译器开始优化之前)。

于 2012-05-19T16:46:47.837 回答
2

我从第二行代码中了解到 ref 的地址(因此是与号)是 a。然后,整数 ref 被赋予 b 的值。

我认为您不了解引用的工作原理。

int a;
int &ref = a;

第一行分配一个int对象。可以使用局部变量来引用此对象a

第二行具有成为ref同一int对象的别名的效果。可以使用a或对对象进行更改ref,但只有一个int对象。

于 2012-05-19T16:49:32.527 回答
1

您需要拿起一本关于 C++ 的好书并阅读它,因为您的问题中有许多基本的错误陈述。

首先,a 不是 ref 的地址。当您&在第一行代码中使用运算符时: int &ref = a 您没有设置refto的地址a。您正在创建一个新变量,它是现有整数的别名,即对a. 这是它自己的运算符/操作,与地址或指针无关(不是真的)。

此后任何时候你读或写ref,就好像你在写一个。ref现在是另一种说法a,您对其执行的任何操作(包括尝试获取其地址)都将转发a.

于 2012-05-19T16:50:17.330 回答
1

即使不涉及函数调用,别名也有很好的用途。

您可以使用它来简化名称

MyComplicatedStruct x;
int &ref = x.array[17].anotherarray[3];
// Do stuff with 'ref'

每次我想使用该整数值时都必须将其拼写出来,这会很痛苦(而且容易出错!)。

另一个例子:

int myFirstValue = 1;
int MyOtherValue = 2;

while(true) {
    int &value = (SomeComplicatedTest() ? myFirstValue : myOtherValue);
    // do stuff with 'value'
}

如果没有参考,这也将是一种痛苦(并且容易出错)。

于 2012-05-19T17:06:13.817 回答