私は、C++11 のムーブ セマンティクスがどのように機能するかについて頭を悩ませようとしてきましたが、ムーブ元オブジェクトが満たす必要がある条件を理解するのにかなりの苦労をしています。セマンティクスを移動するという議論はpimplsに最適です。
私の問題の最も簡単な例は、次のような pimpl イディオムに関係しています。
class Foo {
std::unique_ptr<FooImpl> impl_;
public:
// Inlining FooImpl's constructors for brevity's sake; otherwise it
// defeats the point.
Foo() : impl_(new FooImpl()) {}
Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {}
Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {}
Foo & operator=(Foo rhs)
{
std::swap(impl_, rhs.impl_);
return *this;
}
void do_stuff ()
{
impl_->do_stuff;
}
};
では、引っ越してきた後はどうすればよいのFoo
でしょうか。移動元のオブジェクトを安全に破棄し、割り当てることができます。どちらも非常に重要です。ただし、 でやろうとするdo_stuff
とFoo
爆発します。の定義にムーブ セマンティクスを追加する前はFoo
、everyFoo
は できるという不変条件を満たしていましたがdo_stuff
、それはもはや当てはまりません。(たとえば)moved-fromFoo
を配置すると、新しい動的割り当てが必要になり、移動セマンティクスの目的が部分的に無効になるため、優れた代替手段はあまりないようです。impl_
入っているかどうかを確認do_stuff
して、デフォルトに初期化できましたFooImpl
そうであれば、それは(通常は偽の)チェックを追加します。メソッドがたくさんある場合は、すべてのメソッドでチェックを行うことを忘れないでください。
do_stuff
できることは合理的な不変条件であるという考えをあきらめるべきですか?