【问题标题】:Is a reference returned from a temporary variable valid?从临时变量返回的引用是否有效?
【发布时间】:2015-02-18 11:27:14
【问题描述】:

我遇到过一种情况,能够将方法调用链接到临时变量会非常有帮助:

draw(Quad(0, 0, 1, 1).rotate(90));  // <-- .rotate() returns a Quad reference

struct Quad{
    Quad(float x, float y, float width, float height){...}
    Quad & rotate(float degrees){
        ...
        return *this;
    }
}

但是,我不确定临时变量是否会保持足够长的时间以供draw() 函数使用它。这样做安全吗?

【问题讨论】:

标签: c++ chaining object-lifetime


【解决方案1】:

这种特殊用途是安全的。临时持续到创建它的完整表达式结束;这里,完整表达式是整个语句,包括对draw 的调用。

一般来说,这种模式可能很危险。以下给出了未定义的行为:

Quad & rotated = Quad(0, 0, 1, 1).rotate(90);
draw(rotated);

在我看来,我希望类型是不可变的;与其调用函数来修改现有对象,不如调用const 函数返回一个新对象,同时保持现有对象不变。

除非将其直接绑定到引用,这会延长其生命周期以匹配引用。这不适用于这里,因为它没有直接绑定。

【讨论】:

  • 我比我更喜欢您的回答,因为您实际上设法就如何编写更好的课程提出了具体建议,而我无法做到这一点。让我们一起去吧。 :)
  • 我同意。但是赋值运算符的约定不是相同的模式吗?如果这种模式很危险,那是否意味着赋值运算符出于同样的原因也很危险?
  • @ChrisDrew:是的,传统的类赋值运算符也返回引用,所以像T &amp; t = (T() = x); 这样奇怪的东西会给你一个悬空引用。但是明智的代码不太可能分配给临时的,或者将分配的结果绑定到引用,除非你同时做这两件事,否则没有危险。
【解决方案2】:

是的,临时的Quad 在完整表达式的末尾被销毁(尾随;)。所以当你调用 rotate 时它仍然存在,当你调用 draw 时它仍然存在。

【讨论】:

    猜你喜欢
    • 2012-03-30
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多