私は答えがそうだと思います。このような振る舞いを自分で実装するのはかなり簡単なので、Standardはコンパイラ自体に何らかのルールを課す必要はないと感じました。 C++言語は膨大で、使用する前にすべてを想像することはできません。たとえば、C++のテンプレートを考えてみましょう。それは、今日使用されている方法で最初に使用されるようには設計されていません(つまり、メタプログラミング能力です)。だから、スタンダードはちょうど自由を与え、std::move(other.p)
のための特別なルールを作っていないと思っています。それは設計原則の1つで、"あなたはあなたが使っていないものを支払うことはありません"です。
std::unique_ptr
は移動可能ですが、コピーできません。あなたが望むのであれば、ポインタ、セマンティックの両方の移動とコピー可能であるし、ここでは1つの些細な実装です:
template<typename T>
struct movable_ptr
{
T *pointer;
movable_ptr(T *ptr=0) : pointer(ptr) {}
movable_ptr<T>& operator=(T *ptr) { pointer = ptr; return *this; }
movable_ptr(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
}
movable_ptr<T>& operator=(movable_ptr<T> && other)
{
pointer = other.pointer;
other.pointer = 0;
return *this;
}
T* operator->() const { return pointer; }
T& operator*() const { return *pointer; }
movable_ptr(movable_ptr<T> const & other) = default;
movable_ptr<T> & operator=(movable_ptr<T> const & other) = default;
};
今、あなたはあなた自身の移動・セマンティクスを記述することなく、クラスを書くことができます。
struct T
{
movable_ptr<A> aptr;
movable_ptr<B> bptr;
//...
//and now you could simply say
T(T&&) = default;
T& operator=(T&&) = default;
};
注意をmovable_ptr
はではなく、スマートポインタであるので、コピーセマンティクスとデストラクタを書く必要があります。
なぜでしょうか?あなたが「動かされた」オブジェクトで行うべき唯一のことは、それを無視することです。あなたがもはやポインタを使用しない場合は、クラスが所有していないメモリを指すポインタは問題ではないでしょうか? – hvd
「あなたが使っていないものを支払うことはありません」 –
@hvd:デストラクタは、 'delete p'と言ってもそれを無視しません:) – fredoverflow