_C++11
_では、std::move()
を使用して、オブジェクトの所有権を別の_unique_ptr
_に転送できます。所有権の譲渡後、所有権を譲渡したスマートポインターはnull
になり、get()
は_nullptr.
_を返します。
_std::unique_ptr<int> p1(new int(42));
std::unique_ptr<int> p2 = std::move(p1); // Transfer ownership
_
所有権を別の_unique_ptr
_に転送しているため、これが役立つ状況は何ですか?
次の状況では、あるunique_ptr
から別の_に所有権を移動します。関数から戻り、コンストラクターのような関数にパラメーターとして渡す。
多態型Animal
があるとします:
struct Animal {
virtual ~Animal() {}
virtual void speak() = 0;
};
具体的なサブクラスCat
およびDog
を使用:
struct Cat : Animal {
void speak() override { std::cout << "Meow!\n"; }
};
struct Dog : Animal {
void speak() override { std::cout << "Woof!\n"; }
};
そして、必要な服従の価値に基づいてペットを作成する単純な工場が必要です。次に、ファクトリはポインタを返す必要があります。作成されたペットの所有権を呼び出し元に転送するために、ペットファクトリーに必要な戻り値の型はstd::unique_ptr<Animal>
です。
std::unique_ptr<Animal> createPet(double obedience) {
if (obedience > 5.0)
return std::make_unique<Dog>();
return std::make_unique<Cat>();
}
ここで、ペットを所有するHouse
を作成する場合、House
のコンストラクターにペットを渡すことができます。 unique_ptr
をコンストラクターに渡す最善の方法については、いくつかの議論があります( このブログ投稿のコメントを参照 )が、次のようになります。
class House {
private:
std::unique_ptr<Animal> pet_;
public:
House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {}
};
unique_ptr
をコンストラクターに渡し、それをメンバー変数に「移動」しました。
呼び出しコードは次のようになります。
auto pet = createPet(6.0);
House house(std::move(pet));
House
を作成した後、pet
にペットの所有権を譲渡したため、nullptr
変数はHouse
になります。
たとえば、関数を呼び出す場合は、パラメータリストでunique_ptr
をmove
できるため、関数シグネチャの一部になります。
foo ( std::unique_ptr<T>&& ptr )
fooを呼び出すことができます
foo( std::move(myPtr) );
std::move
は無条件キャストであり、unique_ptr
は状態を持つオブジェクトであり、その状態の一部はunique_ptr
が管理しているポインターであり、std::move
を使用するとオブジェクト全体をキャストすることになります。 std::unique_ptr
は無条件のキャストであり、std::move
が単にキャストされると言ったので、std::move
は実際には特定のものを何も気にしないので、unique_ptr
の使用中にunique_ptr<T>
に特有のことはありません。
unique_ptr
が指すオブジェクトの所有権の移転について話したい場合は、 std::unique_ptr<T>
自体が提供するswap
を考慮する必要があります。