3

我已经“继承”了一个设计,我们在应用程序退出时使用一些全局对象来做事情(更新应用程序状态日志文件等......对这个问题并不重要)。

基本上,应用程序创建特定类的虚拟助手对象,并让它们的析构函数在应用程序正常退出或遇到错误时执行这些额外的工作(并且应用程序知道在所有情况下要做什么,同样与问题无关) .

但是现在我遇到了一种情况,我不想调用这些析构函数,只是离开应用程序而不执行这些“终止作业”。我怎样才能以一种体面的、独立于平台的方式做到这一点?我不想要一个解决方案,例如除以零:)

编辑:我知道设计坏了 :) 我们正在努力修复它。

Edit2:我想避免任何异常退出的“痕迹”......对不起,迟到的规范。

Edit3:获得对析构函数源代码的访问权以修改它们是非常困难的。当政客接管键盘并尝试编写程序时,就会发生这种情况。我们只知道,“他们的”析构函数将在退出时运行......

4

5 回答 5

5
abort();

中止当前进程,产生异常的程序终止。

该函数引发 SIGABRT 信号(就像调用 raise(SIGABRT) 一样)。如果未被捕获,这将导致程序终止,将依赖于平台的不成功终止错误代码返回给主机环境。

程序在不破坏任何对象且不调用任何传递给 atexit 或 at_quick_exit 的函数的情况下终止。

于 2013-11-04T14:01:26.157 回答
5

我怎样才能以一种体面的、独立于平台的方式做到这一点?

你不能。至少不是以一种体面的方式。

您可以通过throwing 异常而不是catching 来完成此操作。最终结果将是您的应用程序将非常不优雅地终止。不会调用析构函数。这非常丑陋,非常骇人听闻。如果您的设计依赖于这种行为来正常运行,那么您的设计不仅是完全错乱的,而且几乎不可能维护。

我宁愿在您不想为其运行析构函数的对象中设置一个布尔标志。如果设置了这个标志,那么销毁代码将不会运行。析构函数仍会触发,但可以跳过您想要避免运行的实际代码。


如果您控制全局的构建,则可以利用 operator placement-new。为你的全局构建一个char足够大的全局缓冲区,然后是placement-new你的全局缓冲区。由于以这种方式构造的对象必须通过显式调用析构函数来销毁,所以不要在全局关闭时调用析构函数。

于 2013-11-04T14:04:26.143 回答
0

最简单的方法是用堆分配的指向对象的指针替换全局对象。这样,为了运行它们的析构函数,您必须手动操作delete它们。请注意,这当然非常非常讨厌。比使用原始指针更好的方法是使用 a std::unique_ptrand,以防不应该调用析构函数release

如果您不想更改与全局对象交互的客户端代码(并期望非指针类型),只需将实际指针包装到全局代理对象中即可。

(PS:这种设计的原因很少但非常合理。有时调用析构函数是完全安全的,调用它们可能是有害的,例如因为已知它们只释放内存,但由于许多嵌套而需要很长时间析构函数调用。这仍然需要非常小心地完成,但绝不是“糟糕的设计”。)

于 2013-11-04T14:10:58.647 回答
0

它很丑,但它有效:

  1. 创建简单的制造商类。

  2. Maker 的构造函数应该分配您喜欢的对象并将其分配给静态指针。

  3. 确保在制造商的析构函数中没有做任何事情。

  4. 创建制造商对象的单个静态实例。

  5. 为了让事情看起来更好,将静态指针设为私有并编写内联访问器函数,该函数会将您拥有的静态指针转换为公共引用。

于 2014-01-29T01:27:19.353 回答
0

接受您对“我们知道它坏了”的评论......

在某处放置一个全局布尔值

bool isExiting;

退出时将此设置为 true。

在你的析构函数中

if( !global::isExiting )
{
   // destruction code here
}

躲到某个地方,并感到非常羞愧。

于 2013-11-04T14:07:52.267 回答