std::unique_ptr删除顺序有保证吗?

Is std::unique_ptr deletion order guaranteed?

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

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 是否保证内存将按此顺序释放?

我想过让所有的manager都成为全局单例,但觉得如果可以的话,这种方式会更好。

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

是的,保证销毁顺序

一旦欠 std::unique_ptr 被销毁,每个删除器都会被调用 ref, and the std::unique_ptrs are destroyed in reverse order of their construction when they all go out of scope togetherref.

但是,此顺序与您在 App::App() 中的分配顺序没有直接关系 — 您可以调换它们,但不会有任何改变。重要的是 std::unique_ptrApp 中的声明顺序。

因此,虽然销毁顺序得到保证,但它可能不是您期望的顺序。

std::unique_ptr 不控制何时调用其析构函数。相反,它的声明位置决定了它的销毁顺序。

Class 成员按照它们在 class 主体中声明的顺序构造,并以相反的顺序销毁。因此,在您的情况下,当构造 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>()) {}

如果你不想默认构造指针然后赋值给它们