单例破坏的atexit:失败案例
atexit for singleton destruction : failure case
来源:https://sourcemaking.com/design_patterns/to_kill_a_singleton
有一点是肯定的:如果单例析构函数相互依赖。另一种选择是完全避开驱逐舰,而依赖草案标准atexit()函数,正如Tim Peierls向我建议的那样:我坚持atexit()是一个很好的方法来清理C++中的singleton想要具有程序生存期且没有替换的单个实例。
标准草案承诺了很多:函数atexit()可以是用于指定要在退出时调用的函数。如果atexit()调用时,实现不应破坏初始化的对象在atexit()调用之前,直到在已调用atexit()调用。
我能看到这种失败的唯一方法是如果其析构函数依赖于Singleton实例的对象已初始化在之后,构造Singleton实例,即通过其他一些静态初始化。这表明类具有静态实例应避免在销毁过程中依赖于singleton。(或者至少应该有一种方法让这些类检查辛格尔顿在毁灭过程中的存在。)
我无法理解最后一段,即在什么情况下会失败以及如何失败。
有人能给它点光吗?
由于使用atexit
而不是析构函数来清理Singleton,因此可以更改对象清理的顺序。例如:
Singleton S;
Object O;
// later in code:
Call atexit() to register cleanup function for S
通常,这些对象的销毁顺序是O,然后是S,但添加了atexit
调用后,这是相反的,因此S在atexit
调用中被清除,然后O被销毁。如果O的析构函数以任何方式依赖于Singleton s,那么在该析构函数运行时,您将有未定义的行为。
避免这种情况的方法是在构造任何依赖于它的对象之前,调用atexit
来注册Singleton清理函数。如果O本身是一个静态对象,这可能很棘手,并且可能需要创建一个类,该类的构造函数调用atexit
,以便将其插入两个静态对象之间。
Singleton S;
struct SAtExit {
SAtExit() { atexit(...); }
} SCleanup;
Object O;
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- shared_ptr和weak_ptr失败的琐碎案例
- 通读getchar_unlocked失败案例
- 单例破坏的atexit:失败案例