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_ptr
s are destroyed in reverse order of their construction when they all go out of scope togetherref.
但是,此顺序与您在 App::App()
中的分配顺序没有直接关系 — 您可以调换它们,但不会有任何改变。重要的是 std::unique_ptr
在 App
中的声明顺序。
因此,虽然销毁顺序得到保证,但它可能不是您期望的顺序。
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>()) {}
如果你不想默认构造指针然后赋值给它们
我正在制作一个控制我的应用程序的全局单例,我希望子系统按特定顺序启动和关闭。
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_ptr
s are destroyed in reverse order of their construction when they all go out of scope togetherref.
但是,此顺序与您在 App::App()
中的分配顺序没有直接关系 — 您可以调换它们,但不会有任何改变。重要的是 std::unique_ptr
在 App
中的声明顺序。
因此,虽然销毁顺序得到保证,但它可能不是您期望的顺序。
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>()) {}
如果你不想默认构造指针然后赋值给它们