34

このコードフラグメントは有効ですか?:

unique_ptr<A> p(new A());
p = nullptr;

つまり、に割り当てることはできnullptrますunique_ptrか?またはそれは失敗しますか?

これをg++コンパイラで試しましたが、機能しましたが、他のコンパイラはどうでしょうか。

4

2 に答える 2

52

それは動作します。

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_tnullptrnullptrunique_ptrunique_ptr

したがって、この割り当ての後、Aオブジェクトは破棄されます。

于 2013-02-25T15:55:28.403 に答える
2

より一般的なケース:

#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()
于 2019-07-16T00:07:10.870 に答える