我想使用
创建一个对象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()
语法,但似乎引用不允许这样做。任何解决方案吗?
答案 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
是合法的。