在Shutdown()方法而不是析构函数中进行清理 [英] Cleaning up in Shutdown() method instead of destructor

查看:78
本文介绍了在Shutdown()方法而不是析构函数中进行清理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rastertek DirectX教程中,它们具有空的构造函数和析构函数,而使用 initialize() shutdown()函数用于对象初始化和清理。使用这种设计一段时间后,我可以稍微了解使用 initialize()方法的好处,但是我看不到如何使用关机()方法比将所有清理代码都放在析构函数中更好。

In Rastertek DirectX tutorials they have empty constructors and destructors and instead use initialize() and shutdown() functions for objects initialization and cleaning up. After using this design for a while I can somewhat understand the benefits of having an initialize() method, but I can't see how using a shutdown() method is any better than putting all the clean-up code in the destructor.

它们提供的原因如下:

The reason they provide is the following:


您还将注意到我没有在类析构函数中进行任何对象清理。相反,我在Shutdown函数中对所有对象进行了清理,您将进一步了解。原因是我不相信它被称为。某些Windows函数(例如ExitThread())以不调用类析构函数而导致内存泄漏而闻名。当然,您现在可以调用这些函数的安全版本,但是在Windows上进行编程时请小心。

You will also notice I don't do any object clean up in the class destructor. I instead do all my object clean up in the Shutdown function you will see further down. The reason being is that I don't trust it to be called. Certain windows functions like ExitThread() are known for not calling your class destructors resulting in memory leaks. You can of course call safer versions of these functions now but I'm just being careful when programming on windows.

所以一般用法模式如下:

So the general usage pattern looks like this:

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 ++中还没有必要(因为这会使使用智能指针更加困难)。

When looking at Rastertek's code it seems to me that they're coming from C background (initializing all variables at the top of the function, using only raw pointers and raw arrays etc.), so I wonder if this is yet another thing that is unnecessary in modern C++ (for one it makes it more difficult to use smart pointers). Is there any real benefit to this design?

推荐答案

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

Generally, it is a bad advice not to do a cleanup in the destructor.

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

But you can do it if the clean operation can fail, and you want to throw an exception. Then you have to be careful, as another exception would call abort(). For that particular case, doing cleanup in a separate function makes sense.

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

By the way, the code example indeed looks like from someone coming from the c world.


原因是我不相信它会被调用。某些Windows函数(例如ExitThread())因未调用类析构函数而导致内存泄漏而闻名。

The reason being is that I don't trust it to be called. Certain windows functions like ExitThread() are known for not calling your class destructors resulting in memory leaks.

这是正确的,但是尝试避免这种功能。同样来自此处

That is correct, but try to avoid such functions. Also from here :


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

There is no portable way in C++11 (that I'm aware of) to non-cooperatively kill a single thread in a multi-thread program (i.e. without killing all threads).

因此只需让线程顺利完成,然后将调用析构函数。

therefore just let the thread nicely finish, and destructors will be called.

这篇关于在Shutdown()方法而不是析构函数中进行清理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆