C++ unique_ptr 可以采用 nullptr 值吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15070862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:59:01  来源:igfitidea点击:

Can a unique_ptr take a nullptr value?

c++c++11pointersunique-ptrnullptr

提问by Zhen

Is this code fragment valid? :

这个代码片段有效吗?:

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

That is, can I assign nullptrto a unique_ptr? or it will fail?

也就是说,我可以分配nullptr给 aunique_ptr吗?还是会失败?

I tried this with the g++compiler and it worked, but what about other compilers?

我用g++编译器尝试了这个并且它工作了,但是其他编译器呢?

回答by Andy Prowl

It will work.

它会起作用

From Paragraphs 20.7.1.2.3/8-9 of the C++11 Standard about the unique_ptr<>class template:

来自 C++11 标准关于unique_ptr<>类模板的第 20.7.1.2.3/8-9 段:

unique_ptr& operator=(nullptr_t) noexcept;

Effects: reset().

Postcondition: get() == nullptr

unique_ptr& operator=(nullptr_t) noexcept;

效果reset()

后置条件get() == nullptr

This means that the definition of class template unique_ptr<>includes an overload of operator =that accepts a value of type nullptr_t(such as nullptr) as its right hand side; the paragraph also specifies that assigning nullptrto a unique_ptris equivalent to resetting the unique_ptr.

这意味着类模板的定义unique_ptr<>包括一个重载,operator =它接受一个类型nullptr_t(例如nullptr)的值作为它的右手边;该段落还指定分配nullptr给 aunique_ptr等效于重置unique_ptr

Thus, after this assignment, your Aobject will be destroyed.

因此,在此分配之后,您的A对象将被销毁。

回答by mrgloom

More common case:

更常见的情况:

#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);
}

Output:

输出:

A::A()
B::B()
B::~B()
A::~A()

This code example can be non-intuitive:

此代码示例可能不直观:

#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);
}

Output:

输出:

A::A()
B::B()
pA not nullptr!
A::~A()
B::~B()