バックグラウンド
今日の初めに次の回答を読みましたが、文字通り C++ を再学習するように感じました。
次に、これらのエキサイティングな機能を使用する「方法」を変更する必要があるかどうかを考えました。私が抱えている主な関心事は、コードの効率と明確さです (前者は後者よりも少し重要です)。これは私をこの投稿に導きました:
私は強く反対します(答えに同意します、つまり)。ポインターを賢く使用しても、効率や明確さの点で移動セマンティクスが冗長になるとは思いません。
質問
現在、重要なオブジェクトを実装するときはいつでも、大まかに次のようにしています。
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&)
};
今日読んだ最初の 2 つの投稿から私が理解していることから、代わりにこれに変更することが有益であるかどうか疑問に思っています。
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)
};
現在、少し複雑で冗長であることを除けば、2 番目の ( struct X
) によってパフォーマンスが向上する状況は見られません。また、読みにくくなっていることがわかります。私の 2 番目のコードがムーブ セマンティクスを正しく使用していると仮定すると、現在の「方法」をどのように改善できますか( struct Y
)?
注1:後者をより明確にする唯一の状況は、「機能から外れる」ことです
X foo()
{
X automatic_var;
// do things
return automatic_var;
}
// ...
X obj( foo() );
を使用する代替案を考えていstd::shared_ptr
ます。std::reference_wrapper
飽きたら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() );
わずかに明確ではありませんが、効率的です。
注 2:私は、この質問を正確かつ回答可能なものにし、議論の対象にならないようにするために本当に努力しました。よく考えて、「なぜ移動セマンティクスが役立つのか」と解釈しないでください。これは私が求めていることではありません。