Reputation: 13936
I have an Object that should not be copied, but only moved, and so I've tried to ensure that a function returns the T&&
of the object. My problem is that the object is being destroyed before it returns and I don't know how to do this properly.
#include <iostream>
class Foo
{public:
Foo() {
a = new int;
std::cout << a << '\n';
}
Foo(const Foo& other) = delete;
Foo(Foo&& other) {
a = other.a; other.a = nullptr;
}
~Foo() {
std::cout << a << '\n';
delete a;
}
void operator= (const Foo& other) = delete;
void operator= (Foo&& other) {
a = other.a;
other.a = nullptr;
}
int* a;
};
Foo&& createNewFoo()
{
return std::move(Foo());
}
int main()
{
Foo foo = createNewFoo(); // The pointer is deleted before this assigns to foo
}
Upvotes: 1
Views: 810
Reputation: 12263
You can just do the following:
static Foo createNewFoo() {
return Foo();
}
Since Foo()
is already an r-value, no std::move
is needed.
Upvotes: 2
Reputation: 172934
You're constructing a temporary object and binding it to the rvalue-reference as the return value, the temporary will be destroyed after the full expression immediately then the returned reference is always dangled.
Changing the function to return-by-value would be fine; rvalue would be moved to the return value.
Foo createNewFoo()
{
return Foo();
}
BTW: For the above code, Foo foo = createNewFoo();
won't copy/move anything due to copy elision, which is guaranteed since C++17.
EDIT
So why isn't the temporary destroyed immediately when returning
return Foo();
For return-by-value, the order of returning is
For return-by-reference, the order is
Upvotes: 4