使用前参考破坏对象

时间:2015-06-12 10:23:28

标签: c++

我想使用

创建一个对象
object().addSomething().addSomethingElse()

语法然后在代码的一部分中使用它,但以下代码将不起作用:

class myObj {
public:
 myObj() {}
 ~myObj() { std::cout << "dtor called" << std::endl; }
 myObj& someOtherOperation() {
  return *this;   
 }
};

int main() {
    auto& elementRef = myObj().someOtherOperation();
    {
        std::cout << "some stuff that uses elementRef" << std::endl;
    }  
}

析构函数在使用引用的代码部分之前被称为

我想避免昂贵的对象复制操作并保留

object().addSomething().addSomethingElse()

语法,但似乎引用不允许这样做。任何解决方案吗?

4 个答案:

答案 0 :(得分:6)

独立创建对象:

auto o = myObj();

然后自由使用它:

o.someOtherOperation().someOtherOperation();

答案 1 :(得分:1)

当隐式对象参数为右值时,您可以使用移动语义进行优化:

myObj someOtherOperation() & {
    return *this;   
}

myObj someOtherOperation() && {
    return std::move(*this);   
}

差异的一个例子:

auto element = myObj().someOtherOperation(); //uses move semantics
myobj obj;
auto otherElement = obj.someOtherOperation(); //doesn't use move semantics

答案 2 :(得分:1)

是的,有一个特殊的例外,它允许临时工具的生命周期延长,如果他们被绑定到引用,但是当通过一个函数隐藏该绑定时,它不会也不能工作。 int main()可以在完全独立的翻译单元中定义,甚至不会看到someOtherOperation()的正文。

当你有一个左值时,你应该只通过引用返回*this

myObj& someOtherOperation() & {
// -------------------------^--
  ...
  return *this;   
}

当你在rvalue上调用方法时,可以通过从*this移动来按值返回:

myObj someOtherOperation() && {
// ------------------------^^--
  someOtherOperation(); // keep implementation in other overload
  return std::move(*this);
}

答案 3 :(得分:1)

你可以获得生命&#34;扩展&#34;如果你返回对象并将其绑定到引用,即

const Obj& foo = func_returning_an_instance();

在这种情况下,实例保证与引用一样长。

但是,如果您的方法返回引用,则不会对绑定对象进行扩展...因此在

const Obj& r = Obj().ref_retuning_method().ref_returning_method();

表达式将被正确计算(即Obj实例将足够用于计算完整表达式,从而允许第一次调用返回的引用对第二次调用也有效),但对象将在参考r初始化后立即停止使用,并且在其之后使用r是合法的。