我已经“继承”了一个设计,我们在应用程序退出时使用一些全局对象来执行操作(更新应用程序状态日志文件等等...对问题不重要)。
基本上,应用程序创建特定类的虚拟辅助对象,并允许它们的析构函数在应用程序正常退出或遇到错误时执行这些额外的工作(并且应用程序知道在所有情况下要执行的操作,同样与问题)。
但是现在我遇到了一种我不想调用这些析构函数的情况,只需离开应用程序而不执行这些“终止作业”。我怎样才能以体面的,独立于平台的方式做到这一点?我不想要像零除的解决方案:)
编辑:我知道设计已经破了:)我们正在努力修复它。
Edit2:我想避免任何异常退出的“痕迹”......对于迟到的规范感到抱歉。
Edit3:获取对析构函数的源代码的访问权限以便修改它们非常困难。当政治家接管键盘并尝试编写程序时就会发生这种情况。我们只知道,“他们的”析构函数将在退出时运行...
答案 0 :(得分:5)
abort();
中止当前进程,导致程序异常终止。
该函数引发SIGABRT信号(就好像raise(SIGABRT)一样) 所谓的)。如果未被捕获,则会导致程序终止返回 与主机相关的平台相关的不成功终止错误代码 环境。
程序终止而不会破坏任何对象而不会 调用传递给atexit或at_quick_exit的任何函数。
答案 1 :(得分:5)
我如何以体面,独立于平台的方式做到这一点?
你做不到。至少不是以体面的方式。
您可以通过throw
例外来完成此操作,而不是catch
。最终结果是您的应用程序将非常不合适地终止。不会调用析构函数。这是非常丑陋,非常hackish。如果你的设计依赖于这种行为来正常运行,那么你的设计不仅完全痴呆,而且几乎不可能维护。
我更希望在你不想运行析构函数的对象中设置一个布尔标志。如果设置了此标志,则不会运行销毁代码。析构函数仍将触发,但可以跳过要避免运行的实际代码。
如果您控制全局构建,则可以使用运算符placement-new
。构建一个全局char
缓冲区,其大小足以满足您的全局需求,然后placement-new
您的全局缓冲区。由于必须通过显式调用析构函数来销毁以这种方式构造的对象,因此只需在关闭时调用析构函数即可。
答案 2 :(得分:0)
评论“我们知道它已经破碎了”......
将全球布尔放在某处
bool isExiting;
退出时将此设置为true。
在你的析构函数中
if( !global::isExiting )
{
// destruction code here
}
隐藏在某处,并彻底感到羞耻。
答案 3 :(得分:0)
最简单的方法是通过堆分配指向对象的指针替换全局对象。这样,为了运行它们的析构函数,您必须手动delete
它们。请注意,这当然是非常非常讨厌的。比使用原始指针更好的方法是使用std::unique_ptr
,如果不应该调用析构函数,release
它。
如果您不想更改与全局对象交互的客户端代码(并期望非指针类型),只需将实际指针包装到全局代理对象中。
(PS:这样的设计有很少但非常合理的原因。有时候调用析构函数是完全安全的不,调用它们可能是有害的,例如因为已知它们只释放内存但是由于许多嵌套的析构函数调用会花费很长时间。这仍然需要非常小心地完成,但根本不是“糟糕的设计”。)
答案 4 :(得分:0)
这很难看,但它有效:
创建简单的制造商类。
Maker的构造函数应该分配您喜欢的对象并将其指定给静态指针。
确保在制造商的析构函数中没有任何操作。
创建制造商对象的单个静态实例。
为了让事情看起来更好,请将静态指针设为私有并编写内联访问器函数,该函数将您拥有的静态指针转换为公共引用。