【问题标题】:C++ Is this an "invalid" reference after returning?C ++返回后这是一个“无效”的引用吗?
【发布时间】:2015-10-03 13:31:57
【问题描述】:

这显然很糟糕:

int& GetInvalidIntPtr(){
   int i;
   return i;
}

这是我的例子:

FVector& GetDirectionFromCamera(){ 
   return GetActorLocation() - GetCameraComponent()->GetComponentLocation(); 
}

一个 FVector 基本上包含 3 个浮点数,这就是为什么我想返回引用而不是副本的原因。但是,我相信计算的结果会存储在堆栈中,对吧?
还是因为我立即返回结果而在堆上分配了结果?

【问题讨论】:

  • 这取决于第二个示例中函数和运算符的签名和行为。所以,如果他们返回对在堆上创建的对象的引用,你就可以了。如果没有,你就不行。
  • 不知道operator- 返回什么是不可能的,但正确的答案很简单:返回一个副本,停止尝试优化复制三个浮点数的微小成本。 Keep It Simple, Stupid.

标签: c++ reference scope return


【解决方案1】:

或者是因为我立即返回结果而在堆上分配了结果?

什么?那怎么会发生呢?编译器不只是神奇地在堆上分配东西,因为你返回的东西超出了范围。

试图优化掉三个浮点数的副本,冒着未定义行为的风险,因为您不了解代码的实际作用,这是一种精神错乱。如果您不知道更好,那么只需返回一份副本。这是简单而安全的选择。它也可能是最快的,因为简单的代码可以让编译器更好地优化。

【讨论】:

    【解决方案2】:

    一个 FVector 基本上可以容纳 3 个浮点数,这就是我想返回的原因 地址而不是副本。

    如果你想返回一个地址,那你为什么要返回一个引用呢?引用不是指针。

    (删除,因为问题已被修改为使用“参考”一词而不是“地址”。)


    但是,我相信计算的结果是存储在堆栈中的吧?

    这实际上取决于您的 operator- 究竟返回什么。您没有向我们展示,所以我们无法确定,但如果操作员只是返回 FVector(应该如此),那么您的代码将无法编译,因为临时的 FVector 不能用于初始化 FVector& .

    通常,您的代码基于这样一种误解,即返回FVector 的副本在某种程度上是不好的。它不是。把函数签名改成FVector GetDirectionFromCamera(),让编译器去掉多余的副本。

    或者是因为我立即返回结果而在堆上分配了结果?

    没有。您所谓的“堆”只有在您使用动态分配时才会发挥作用。

    【讨论】:

    • 我在我的问题中将地址更改为参考。谢谢你的信息。
    猜你喜欢
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    相关资源
    最近更新 更多