このコードフラグメントは有効ですか?:
unique_ptr<A> p(new A());
p = nullptr;
つまり、に割り当てることはできnullptr
ますunique_ptr
か?またはそれは失敗しますか?
これをg++コンパイラで試しましたが、機能しましたが、他のコンパイラはどうでしょうか。
このコードフラグメントは有効ですか?:
unique_ptr<A> p(new A());
p = nullptr;
つまり、に割り当てることはできnullptr
ますunique_ptr
か?またはそれは失敗しますか?
これをg++コンパイラで試しましたが、機能しましたが、他のコンパイラはどうでしょうか。
それは動作します。
unique_ptr<>
クラステンプレートに関するC++11標準のパラグラフ20.7.1.2.3/8-9から:
unique_ptr& operator=(nullptr_t) noexcept
;効果:
reset()
。事後条件:
get() == nullptr
これは、クラステンプレートの定義に、タイプの値(など)を右側として受け入れるunique_ptr<>
オーバーロードが含まれていることを意味します。この段落では、aへの割り当ては。のリセットと同等であるとも指定されています。operator =
nullptr_t
nullptr
nullptr
unique_ptr
unique_ptr
したがって、この割り当ての後、A
オブジェクトは破棄されます。
より一般的なケース:
#include <iostream>
#include <string>
#include <memory>
class A {
public:
A() {std::cout << "A::A()" << std::endl;}
~A() {std::cout << "A::~A()" << std::endl;}
};
class B {
public:
std::unique_ptr<A> pA;
B() {std::cout << "B::B()" << std::endl;}
~B() { std::cout << "B::~B()" << std::endl;}
};
int main()
{
std::unique_ptr<A> p1(new A());
B b;
b.pA = std::move(p1);
}
出力:
A::A()
B::B()
B::~B()
A::~A()
このコード例は直感的ではない可能性があります。
#include <iostream>
#include <string>
#include <memory>
class A {
public:
A() {std::cout << "A::A()" << std::endl;}
~A() {std::cout << "A::~A()" << std::endl;}
};
class B {
public:
std::unique_ptr<A> pA;
B() {std::cout << "B::B()" << std::endl;}
~B()
{
if (pA)
{
std::cout << "pA not nullptr!" << std::endl;
pA = nullptr; // Will call A::~A()
}
std::cout << "B::~B()" << std::endl;
}
};
int main()
{
std::unique_ptr<A> p1(new A());
B b;
b.pA = std::move(p1);
}
出力:
A::A()
B::B()
pA not nullptr!
A::~A()
B::~B()