对变量超出范围的引用

Reference to variable out-of-scope

提问人:Tyler D 提问时间:9/5/2020 最后编辑:Vlad from MoscowTyler D 更新时间:9/5/2020 访问量:602

问:

我做了下面的例子来测试我对参考文献的理解:

#include <iostream>

int test(){
    int a = 1;
    int &b = a;
    return b;
}

int main(int argc, const char * argv[]) {
   
    std::cout << test() << std::endl;
}

我打算做的是编写一个示例,其中引用的变量被销毁。我最初写这个想法是,由于 in 的生命周期在返回 in 时结束,输出 的返回值会产生乱码。然而,令我大吃一惊的是,它实际上确实输出了 1!atestbtesttest

这怎么可能?我在这里错过了什么 - 可以以某种方式继续生活吗?ab

C++ 作用域 参考 return-type function-definition

评论

8赞 463035818_is_not_an_ai 9/5/2020
函数返回值而不是引用
2赞 463035818_is_not_an_ai 9/5/2020
顺便说一句,即使您使用无效的引用,也无法区分乱码 1 和非胡言乱语 1
0赞 Scheff's Cat 9/5/2020
通常,避免 U.B. 比引入 U.B. 更难,但无论如何:在 coliru 上演示
1赞 john 9/5/2020
既不是活着,也不是活着。您的函数返回 中值的副本。似乎您正在尝试理解引用,然后才能理解(默认情况下)函数的返回值是副本而不是引用。如果要真正返回引用,则 .abatestint& test()

答:

4赞 Vlad from Moscow 9/5/2020 #1

该函数不返回对任何对象的引用。它返回一个 int 类型的临时对象,该对象由 b 引用的值进行复制初始化。

int test(){
    int a = 1;
    int &b = a;
    return b;
}

实际上,该函数等效于以下函数,无需使用中间变量

int test(){
    return 1;
}

返回引用意味着函数返回类型应为引用类型。类似的东西

int & test()
{
    int a = 1;
    return a;
}

在这种情况下,编译器将发出一条消息,指出该函数返回对局部变量的引用。

评论

0赞 Peter 9/5/2020
在最后一种情况下,编译器可能会发出消息。该行为实际上是未定义的,这意味着不需要诊断。实际上,默认情况下,大多数现代编译器在这种情况下不会发出任何消息 - 但可以配置为(例如,使用命令行选项来发出更多警告)。
0赞 pgreinhard 9/5/2020 #2

我知道你的困惑从何而来。您认为,因为在赋值 b 期间使用了 (&) 运算符,变量 b 现在包含 a 的内存地址。事实并非如此,与号 (&) 是静音的,这意味着在这种情况下它对变量 b 没有影响。

int test()
{
int a = 1;
int &b = a;
return b;
}

您期望的行为如下所示

int* test()
{
int a = 1;
int *b = nullptr;
b = &a; 
return b;
}

在这种情况下,您返回 b 而不取消引用变量,那么您将获得内存地址而不是数字 1。

评论

0赞 Lukas-T 9/5/2020
“与号(&)引用的是B的地址;”不知道你在这里是什么意思。 是引用,在本例中不是运营商的地址。关于这一点:您的第二个代码段具有错误的返回类型。ba&