Consider this snippet:
class Foo
{
int m_fileDescriptor;
public:
Bar transformIntoBar()
{
Bar bar(m_fileDescriptor);
m_fileDescriptor = -1;
return bar;
}
};
As you can see, once Foo
"transforms" into Bar
, its m_fileDescriptor
becomes -1
, which renders the entire object invalid.
The problem's that users of the class have no way of telling that's going to happen.
One solution would be to declare a friend make_bar()
function
friend Bar make_bar(Foo f);
and make Foo
move-only (which is supposed to happen anyway, I skipped it in the example for brevity). This way, the user has to be aware of the fact, that their Foo
object is going to be moved from and therefore become useless.
There's one serious thing speaking against this solution, however. If there's going to be more methods like this one (e. g. make_baz(Foo f)
, etc.), I'd have to create an entire API of friend helper functions, which is clearly not something desirable.
My question is - is there anything better I could do to scream out loud to the users of my class that once you call it, the object becomes useless?
this
object to be an rvalue reference, as created bystd::move
? E.g.:Bar transformIntoBar() &&
foo
would be an lvalue reference. That's just C++ for you! However, temporaries would already be rvalues. E.g.getFooByValue().transformIntoBar()
would work without explicit moves.