在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 ++中不必要的另一件事(一方面它使得使用智能指针更加困难)。这个设计有什么好处吗?
答案 0 :(得分:1)
通常,不要在析构函数中进行清理是一个不好的建议。
但如果清理操作失败,并且您想抛出异常,则可以执行此操作。然后你必须要小心,因为另一个例外是调用abort()。对于那种特殊情况,在单独的函数中进行清理是有意义的。
顺便说一句,代码示例确实看起来像是来自c世界的人。
原因是我不相信它被召唤。某些类似于ExitThread()的窗口函数因不调用类析构函数而导致内存泄漏。
这是正确的,但要尽量避免这些功能。也来自here:
在C ++ 11中(我知道)没有可移植的方法来非合作地杀死多线程程序中的单个线程(即,不会杀死所有线程)。
因此,只需让线程完成,就会调用析构函数。