使用Shutdown()方法而不是析构函数进行清理

时间:2014-02-01 23:25:33

标签: c++ directx game-engine class-design

Rastertek DirectX tutorials中,它们具有空构造函数和析构函数,而是使用initialize()shutdown()函数进行对象初始化和清理。在使用这个设计一段时间之后,我可以在一定程度上理解使用initialize()方法的好处,但是我无法看到使用shutdown()方法比使用所有清理方法更好析构函数中的代码。

他们提供的原因如下:

  

您还会注意到我没有在类析构函数中清理任何对象。相反,我会在关闭功能中清除所有对象,您将进一步查看。原因是我不相信它被召唤。某些类似于ExitThread()的窗口函数因为不调用类析构函数而导致内存泄漏。你当然可以现在调用这些函数的更安全版本,但我在窗口编程时要小心。

所以一般用法模式如下:

class Renderer
{
public:
    Renderer() { }
    ~Renderer() { }

    bool initialize(...) { /* perform initialization */ }
    void shutdown() { /* clean-up */ }
}; 

Renderer* renderer = new Renderer;
renderer->initialize(...);

// use the renderer

renderer->shutdown();
delete renderer;
renderer = NULL;

在查看Rastertek的代码时,我觉得他们来自C背景(初始化函数顶部的所有变量,只使用原始指针和原始数组等),所以我想知道这是否是现代C ++中不必要的另一件事(一方面它使得使用智能指针更加困难)。这个设计有什么好处吗?

1 个答案:

答案 0 :(得分:1)

通常,不要在析构函数中进行清理是一个不好的建议。

但如果清理操作失败,并且您想抛出异常,则可以执行此操作。然后你必须要小心,因为另一个例外是调用abort()。对于那种特殊情况,在单独的函数中进行清理是有意义的。

顺便说一句,代码示例确实看起来像是来自c世界的人。

  

原因是我不相信它被召唤。某些类似于ExitThread()的窗口函数因不调用类析构函数而导致内存泄漏。

这是正确的,但要尽量避免这些功能。也来自here

  

在C ++ 11中(我知道)没有可移植的方法来非合作地杀死多线程程序中的单个线程(即,不会杀死所有线程)。

因此,只需让线程完成,就会调用析构函数。