显式破坏非指针静态对象

时间:2011-05-25 19:38:26

标签: c++ static destructor

我正在使用Autodesk Maya api,MLibrary::cleanup函数“...阻止执行任何静态析构函数。” source

使用Maya api的代码也使用了一些我的dll,它包含需要销毁的非指针静态变量(特别是包含static Log stdLog的Log类,需要写一个页脚和关闭文件流)。

处理此问题的适当方法是什么?我添加了一个调用Log::destroy()的{​​{1}}函数,这样安全吗?

4 个答案:

答案 0 :(得分:2)

也许它是安全的,也许不是。最好是对代码进行结构化以使其无关紧要。 destroy呼叫~Log,而不是~Log拨打destroy。还要destroy检查对象是否已被销毁;如果必须,添加一个布尔变量来跟踪它。

答案 1 :(得分:1)

我会将静态对象移动到堆对象中,并添加一个调用以允许干净关闭。 如果在非动态对象上显式调用析构函数,那么在程序正常终止的情况下,析构函数将被调用两次,这是IMO错误。

使用显式关闭调用可以正确处理这两种情况(即在没有关闭的情况下正常终止,在显式关闭后正常终止)。

顺便说一下,“复杂”静态实例在我的体验中是一个普遍存在的问题,因为你无法准确控制它们的创建时间和销毁时间。如果构造或破坏可能因任何原因而失败,那么确保将这些对象用作静态持续时间实例意味着您正在寻找麻烦。

另外根据我的经验调试main的第一条指令之前或之后发生的问题比正常调试更难(例如,在Windows中程序关闭期间发生的段错误经常被操作系统静音,在main开始之前调试可能无法正常工作)。

多年来,我已经从懒惰的初始化/破坏转变为启动/关闭的受控确定性方法(如果可能的话),我不会回头。

答案 2 :(得分:0)

如果stdLog的析构函数真的从未调用,那么是的,它是安全的。

答案 3 :(得分:0)

您可以将“静态存储持续时间”对象注册为atexit()on_exit()清理方法作为构建的一部分,并在销毁期间不执行任何操作。

然后注册的方法可以进行所需的清理(例如在日志上打印页脚)。