是否保证std :: unique_ptr删除顺序?

时间:2016-08-16 16:44:39

标签: c++ c++11 destructor

我正在创建一个控制我的应用程序的全局单例,我希望子系统按特定顺序启动和关闭。

class App
{
public:
    App();
    ~App();

    void start();
    void run();
    void shutdown();

private:
    std::unique_ptr<DisplayManager> displayManager;
    std::unique_ptr<Renderer> renderer;
};

构造函数以正确的顺序创建指针

App::App()
{
    displayManager = std::unique_ptr<DisplayManager>(new DisplayManager);
    renderer = std::unique_ptr<Renderer>(new Renderer);
}

我希望以相反的顺序释放unique_ptrs。 std :: unique_ptr是否保证按此顺序释放内存?

我考虑过让所有管理人员成为全球单身人士,但如果能让它成功,我觉得这样会更好。

编辑:我注意到实际问题是实例变量成员被破坏的顺序。在那种情况下是否有保证订单?

2 个答案:

答案 0 :(得分:14)

std::unique_ptr无法控制何时调用析构函数。相反,它是声明它确定它被破坏的顺序的地方。

类成员按照它们在类体中声明的顺序构造,并以该顺序的反向销毁。因此,在构建App的情况下,首先构造displayManager,然后构造renderer。当App实例被销毁时,renderer首先被销毁,然后displayManager被销毁。

另请注意

App::App()
{
    displayManager = std::unique_ptr<DisplayManager>(new DisplayManager);
    renderer = std::unique_ptr<Renderer>(new Renderer);
}

您正在对默认构造的unique_ptr进行分配。您需要使用

之类的成员初始化列表
App::App(): displayManager(new DisplayManager), renderer(new Renderer) {}
// or if you want to be in the don't use new camp
App::App(): displayManager(std::make_unique<DisplayManager>()), renderer(std::make_unique<Renderer>()) {}

如果您不想默认构造指针然后分配它们。

答案 1 :(得分:9)

是的,销毁订单有保障。

一旦欠款std::unique_ptr被销毁 R3RS ,就会调用每个删除器,并且std::unique_ptr s的构造将按其构造的相反顺序销毁它们都在一起超出范围 ref

但是,此订单与App::App()内的作业顺序没有直接关系 - 您可以交换它们,不会发生任何变化。它是std::unique_ptrApp'声明的顺序。

因此,尽管销毁订单有保证,但可能不是您期望的订单。