【问题标题】:C++ Basic concept regarding reference operator return type关于引用运算符返回类型的 C++ 基本概念
【发布时间】:2012-07-07 12:57:36
【问题描述】:

我需要明确一个基本概念。此代码工作正常。有人可以解释一下,如果函数 calDouble 已经返回 int 的地址(引用),为什么我需要在 main int *j = &calDouble(i); 中进一步使用 & 运算符获取int的地址(参考)?谢谢。

int& calDouble(int x)
{
    x = x*2;
    return x;

}

int main(int argc, char *argv[])
{
    int i = 99;
    int *j = &calDouble(i);

    system("PAUSE");
    return EXIT_SUCCESS;
}

【问题讨论】:

  • 您可能应该将int& calDouble(int x) 更改为int& calDouble(int& x),这样您就不会返回对x 的悬空引用。
  • 实际上,您的代码不起作用。您不能将相同的参数视为一个值,然后将其作为引用返回。我觉得你的问题很好。但我也认为它说明了 C++ 语言是什么可怕 - 它让你犯的不正当错误 - 甚至没有给你一个暗示有问题。将这样一个简短的、看似简单的示例乘以对毫无戒心的世界造成的数百万(数十亿?)行(可能有错误)C++ 代码......
  • “工作正常”我的意思是它编译没有错误。
  • @developer:那么,你的编译器有问题,因为我警告过返回对局部变量的引用。
  • @user315052:我知道。但现在这对我来说是一个单独的问题......顺便说一句,你使用的是哪个编译器?

标签: c++ function reference operator-keyword


【解决方案1】:

int& calDouble(int x) 不返回地址,而是对int 的引用。

您需要获取引用的地址才能将其分配给指针。

但是请注意,您的代码会调用未定义的行为。因为您按值传递参数,所以会在函数内部创建它的副本。所以你通过引用返回一个局部变量,这是不合法的。

我认为您的困惑来自&。这可以通过两种方式使用:

  • 应用于变量&x,获取其地址
  • 在声明 int& x 时,它定义了一个引用

引用只是一个别名,是变量的不同名称。

int x = 0;
int& y = x;

现在,xy 指的是同一个变量。

int* z = &x;

获取x的地址。

【讨论】:

  • 地址和参考有什么区别。我想这就是我感到困惑的地方。
  • @developer - 这是一个关于 C++“参考”的好教程:cprogramming.com/tutorial/references.html。 C 有一个“addressof”运算符(“&”),但只有 C++ 有“references”。
  • @Luchain Grigore:在您编辑的答案中做出了很好的解释。你说得对,我对以两种不同方式表现的 & 运算符感到困惑。所以这里的函数“int& calDouble(int &x)”像任何其他引用变量一样返回 x 的引用,而不是值。而引用变量只是变量的别名。它究竟包含什么:它引用的变量的内存地址?
  • @developer 它的实现已定义。但是您应该将其视为别名。一个昵称。无论你在哪里写y,你都应该想到x。 :)
【解决方案2】:

int& 是一个引用类型。它不是地址。

要查看 &calDouble(i) 的作用,请考虑我们是否将其分为两个语句:

int& x = calDouble(i);
... = &x;

calDouble() 函数返回一个引用类型,而前置的& 然后采用返回的address-of。所以类型现在是int*,这就是编译该行的原因。

但是,您的程序表现出未定义的行为!一旦函数结束,calDouble() 中的 x 就会消失。最初存在的值可能仍在内存中,这就是您的程序“工作”的原因。但这在生产代码中是不可靠的,有朝一日,您完美运行的测试程序可能会在部署时崩溃。

由于这种不同的原因,返回对局部变量的引用通常是个坏主意。 (您会看到类方法返回对成员数据的引用,只要对象仍在范围内就可以了,因为这些变量仍然存在。)只需返回一个常规的int 并继续生活。如果您真的担心返回大对象时的性能,优化编译器可以做一些return value optimization

【讨论】:

  • 我知道返回局部变量的引用是个坏主意...我现在并不关心它...我的主要关注点是引用类型和地址。这两者有什么区别。
  • @developer - 见上面我的link
  • 非常感谢您的解释。它也对我有帮助。
猜你喜欢
  • 1970-01-01
  • 2021-09-15
  • 2020-07-24
  • 2017-09-30
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多