赋值后,引用和变量之间有什么实际区别吗?

Is there any practical difference between a reference and a variable after assignment?

本文关键字:什么 区别 之间 引用 变量 赋值      更新时间:2023-10-16

我的理解是,引用基本上是一个指针,其值不会改变,并且总是被取消引用。所以如果我有代码

int& thisIsAReference = someVariable;

然后基本上创建一个指向someVariable位置的指针,并且该指针永远不会指向另一个位置,并且总是被取消引用。

但这似乎与变量是一回事。据我了解,变量引用特定的内存位置,不能引用不同的内存位置,并且隐式引用某个位置的值而不是位置本身。

那么,除了声明的语法不同之外,thisIsAReferencesomeVariable之间有什么区别吗?

是的,你是绝对正确的。在概念层面上,你可以将引用视为同一变量的另一个名称(正如Stroustrup在TC++PL中所说的那样)。反过来:您可以将任何变量视为伪装的引用 - 名称实际上属于引用,它与相同的未命名存储区域相关联。

但是,这就是它在概念级别上的样子。

在实践中,情况可能大不相同。从实际的角度来看,在一般情况下,引用是在后台作为指针实现的。这意味着通过引用进行访问需要对该指针进行隐式运行时取消引用。这使得引用访问的执行速度比"普通"直接变量访问慢。

然而,在许多情况下,编译器可能足够聪明,可以找出引用绑定到什么并消除指针取消引用,将其替换为对目标变量的直接访问。在这种情况下,上述概念("引用只是变量的另一个名称")在实践中得到充分实现。

有一种方法可以区分引用和非引用:当decltype应用于名称时,它将生成该名称声明为具有的类型:

template<typename T>
class foo; //Incomplete type to force compiler error
int main()
{
    int i;        
    int& j = i;
    foo<decltype(i)> x;
    foo<decltype(j)> y;
}

错误:聚合foo<int> x的类型不完整,无法定义
错误:聚合foo<int&> y具有不完整的类型,无法定义

那么,除了声明的语法不同之外,thisIsAReferencesomeVariable之间有什么区别吗?

不考虑读取访问的解析值或写入的解析地址。

您实际上可以将thisIsAReference视为someVariable的别名。

然后基本上创建一个指向someVariable位置的指针,并且该指针永远不会指向另一个位置,并且总是被取消引用。

不,这是一个未指定的实现细节,但可以用作思维导图模型。

之后

int& thisIsAReference = someVariable;

thisIsAReferencesomeVariable之间没有区别.引用是一个别名,即每当你写someVariable你也可以写thisIsAReference。但是,引用不是"与变量相同的东西",因为

int thisIsNotAReference = someVariable;
thisIsNotAReference = 20; // someVariable still has the old value

而有参考

int& thisIsAReference = someVariable;
thisIsAReference = 20;    // now someVariable == 20 

你是对的,变量引用特定位置的值,指针将引用位置的地址。与指针相反,引用的一个独特之处在于,您永远不会有 NULL 值。引用必须在创建时初始化,并且一旦初始化,就无法更改。与变量相比,这是一个巨大的差异,因为我可以不断更改变量的值,这就是变量如此有用的原因。