Background
I read the following answers earlier today, and it felt like relearning C++, litterally.
What is the copy-and-swap idiom?
Then I wondered if I should change my "ways" to use these exciting features; the main concerns I have are for code efficiency and clarity (former slightly more important than the latter to me). This lead me to this post:
with which I strongly disagree (I agree with the answer, that is); I don't think a smart use of pointers could ever make move semantics redundant, neither in terms of efficiency nor clarity.
Question
Currently, whenever I implement a non-trivial object, I roughly do this:
struct Y
{
// Implement
Y();
void clear();
Y& operator= ( const& Y );
// Dependent
~Y() { clear(); }
Y( const Y& that )
: Y()
{
operator=(that);
}
// Y(Y&&): no need, use Y(const Y&)
// Y& operator=(Y&&): no need, use Y& operator=(const Y&)
};
From what I understand from the two first posts I read today, I am wondering whether it would be beneficial to change to this instead:
struct X
{
// Implement
X();
X( const X& );
void clear();
void swap( X& );
// Dependent
~X() { clear(); }
X( X&& that )
: X()
{
swap(that);
// now: that <=> X()
// and that.~X() will be called shortly
}
X& operator= ( X that ) // uses either X( X&& ) or X( const X& )
{
swap(that);
return *this;
// now: that.~X() is called
}
// X& operator=(X&&): no need, use X& operator=(X)
};
Now, aside from being slightly more complicated and verbose, I don't see a situation in which the second (struct X
) would yield a performance improvement, and I find that it is also less readable. Assuming my second code is using move-semantics correctly, how would it improve my current "way" of doing things (struct Y
)?
Note 1: The only situation which I think makes the latter clearer is for "moving out of function"
X foo()
{
X automatic_var;
// do things
return automatic_var;
}
// ...
X obj( foo() );
for which I think the alternative using std::shared_ptr
, and std::reference_wrapper
if I get tired of get()
std::shared_ptr<Y> foo()
{
std::shared_ptr<Y> sptr( new Y() );
// do things
return sptr;
}
// ...
auto sptr = foo();
std::reference_wrapper<Y> ref( *ptr.get() );
is only slightly less clear, but as efficient.
Note 2: I really made an effort to make this question precise and answerable, and not subject to discussion; please think it through and don't interpret it as "Why are move-semantics useful", this is not what I am asking.
Aucun commentaire:
Enregistrer un commentaire