Destruction object reference before use
I would like to create an object using
object().addSomething().addSomethingElse()
and then use it in a piece of code, but the following code won't work:
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;
}
}
the destructor is called before the part of the code that uses the reference.
I would like to avoid an expensive object copy operation and keep
object().addSomething().addSomethingElse()
but it seems the links don't allow it. Any solutions for this?
source to share
You can optimize using move semantics when the implicit object parameter is rvalue:
myObj someOtherOperation() & {
return *this;
}
myObj someOtherOperation() && {
return std::move(*this);
}
An example of the difference:
auto element = myObj().someOtherOperation(); //uses move semantics
myobj obj;
auto otherElement = obj.someOtherOperation(); //doesn't use move semantics
source to share
Yes, there is a special exception that allows you to extend the lifetime of time series if they are linked to links, but when this anchor is hidden through a function, it does not and cannot work. int main()
can be defined in a completely separate translation unit where he doesn't even see the body someOtherOperation()
.
You should *this
only return by reference if you have an lvalue.
myObj& someOtherOperation() & {
// -------------------------^--
...
return *this;
}
You can return by value by moving from *this
when your method is called on an rvalue:
myObj someOtherOperation() && {
// ------------------------^^--
someOtherOperation(); // keep implementation in other overload
return std::move(*this);
}
source to share
You can get an "extension" of life if you return an object and bind it to a link i.e.
const Obj& foo = func_returning_an_instance();
in this case, the instance is guaranteed to live as long as the link.
If, however, your method returns a link , the expansion of the binding object is not done ... so in
const Obj& r = Obj().ref_retuning_method().ref_returning_method();
the expression will evaluate correctly (i.e. the instance Obj
will live long enough to evaluate the full expression, which allows the reference returned by the first call to be returned for the second call), but the object will expire its life immediately after the reference is initialized r
, and won't be legally used afterwards r
...
source to share