什么是落后两步对象毁灭的理由? [英] What is the reasoning behind two-step object destruction?

查看:172
本文介绍了什么是落后两步对象毁灭的理由?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在游戏开发世界,我经常看到使用类单独的初始化()未初始化()关机()方法。这不仅包括多个教程,而且历史悠久的大型真实世界的项目,像一些现代的游戏引擎。我最近看到惊魂3引擎一类,它不仅采用了关机()方法,但竟把调用这一点。〜富()从它,这基于我知道的一切关于C ++,不能真正算是一个不错的设计。

In the games development world I often see classes using separate initialize() and uninitialize() or shutdown() methods. This includes not only multiple tutorials, but also long-established and large real-world projects, like some modern game engines. I've recently seen a class in Cry Engine 3 which not only uses a shutdown() method, but goes as far as calling this.~Foo() from it, which based on everything I know about C++, can't really be considered a good design.

虽然我可以看到一些是来自两个步骤的初始化的好处,并有很多关于它的讨论,我无法理解两步毁灭背后的原因。为什么不使用由C ++语言中的析构函数的形式提供的默认设备,但有一个独立的关机()方法和析构函数空?为什么更进一步不去,用现代C ++,把一个对象到智能指针持有的所有资源,所以我们不必担心手动释放它们。

While I can see some of the benefits that come from two-step initialization, and there are many discussions about it, I can't understand the reasoning behind the two-step destruction. Why not use the default facilities provided by C++ language in form of the destructor, but have a separate shutdown() method and the destructor left empty? Why not go even further and, using modern C++, put all the resources held by an object into smart pointers so we don't have to worry about releasing them manually.

时的两步破坏基于不再适用,或是否有使用过它控制对象的生命周期的标准方法的一些正当的理由原则有些过时的设计?

Is two-step destruction some outdated design based on principles that no longer apply or are there some valid reasons to use it over standard ways of controlling objects' lifetime?

推荐答案

如果你不想读的要点是,您需要的例外,从构建函数和异常返回错误都是不好的。

If you don't want to read, the gist is that you need exceptions to return errors from ctors and exceptions are bad.

作为Trevor和其他在已经暗示,也有许多原因这种做法。你已经长大href=\"http://www.rastertek.com/dx11tut03.html\"这里rel=\"nofollow\">一个具体的例子,虽然的,所以让我们解决

As Trevor and others have hinted at, there are a number of reasons for this practice. You've brought up a specific example here though, so let's address that.

一类教程交易 GraphicsClass (名字肯定不会激发信心),其中包含这些定义:

The tutorial deals with a class GraphicsClass (the name sure doesn't inspire confidence) which contains these definitions:

class GraphicsClass
{
public:
    GraphicsClass();
    ~GraphicsClass();
    bool Initialize(int, int, HWND);
    void Shutdown();
};

因此​​具有构造函数,析构函数和初始化/关机。为什么不凝结后者向前者?实施给出了一些线索:

So it has ctor, dtor, and Initialize/Shutdown. Why not condense the latter into the former? The implementation gives a few clues:

bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hwnd)
{
    bool result;

    // Create the Direct3D object.
    m_D3D = new D3DClass;
    if(!m_D3D)
    {
        return false;
    }

    // Initialize the Direct3D object.
    result = m_D3D->Initialize(screenWidth, screenHeight, VSYNC_ENABLED, hwnd, FULL_SCREEN, SCREEN_DEPTH, SCREEN_NEAR);
    if(!result)
    {
        MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK);
        return false;
    }

    return true;
}

好了肯定,检查是否新D3DClass 失败的的意义(这只有当我们用完内存的和发生的<一个href=\"http://stackoverflow.com/questions/2497151/can-the-c-new-operator-ever-throw-an-exception-in-real-life\">we've覆盖来不丢 bad_alloc )*。检查,看看 D3DClass ::初始化()失败,可能不是,但。作为其标志性暗示,它试图初始化相关的图形硬件一些资源,可以在正常的情况下有时会失败 - 也许要求的分辨率太高,或资源正在使用中。我们会想处理的优雅,我们不能在构造函数返回错误,我们只能抛出异常。

Ok sure, checking to see if new D3DClass fails is pointless (it only happens if we run out of memory and we've overridden new to not throw bad_alloc)*. Checking to see D3DClass::Initialize() fails may not be though. As its signature hints at, it's trying to initialise some resources related to graphics hardware, which can sometimes fail in normal circumstances - maybe the resolution requested is too high, or the resource is in use. We'd want to handle that gracefully, and we can't return errors in the ctor, we can only throw exceptions.

这当然引发了一个问题:我们为什么不抛出异常? <一href=\"http://programmers.stackexchange.com/questions/113479/are-there-any-real-world-cases-for-c-without-exceptions\">C++例外是非常缓慢。缓慢,它的意见都很强,<一个href=\"http://gamedev.stackexchange.com/questions/2762/throwing-exceptions-in-c-game-dlls-pros-and-cons\">especially在游戏开发。加上你不能在析构函数扔了,所以有乐趣想说,把网络资源终止存在。大多数,如果不是全部,C ++游戏已与异常断开。

Which of course raises the question: why don't we throw exceptions? C++ exceptions are very slow. So slow that opinions of it are very strong, especially in game development. Plus you can't throw in the dtor, so have fun trying to say, put network resource termination there. Most, if not all, C++ games have been made with exceptions turned off.

这是无论如何的主要原因;我不能忽视尽管其他,有时愚蠢,原因,如具有C遗留(那里没有构建函数/ dtors),或具有对模块A和B保持引用彼此的架构。当然记得游戏开发的<一个href=\"http://gamedev.stackexchange.com/questions/3426/why-are-mvc-tdd-not-employed-more-in-game-architecture\">#1当务之急是要出货的游戏,不能创造完美的稳健和维护架构,所以你有时会看到这样愚蠢的做法。

That's the main reason anyway; I can't discount other, sometimes sillier, reasons though, such as having a C legacy (where there are no ctors/dtors), or an architecture that has pairs of modules A and B hold references to each other. Of course remember games development's #1 priority is to ship games, not create perfectly robust and maintainable architectures, so you sometimes see silly practices like this.

我听说,在C ++委员会深切意识到异常有问题,但IIRC最新的是,它被放在太硬斗,所以你会看到在游戏中更多的这种多年来了。

I hear that the C++ committee is deeply aware of the problems that exceptions have, but iirc the latest is that it's been put in the "too hard" bucket, so you'll see more of this in games for many years to come.

* - 啊哈!所以,检查是否新D3DClass 不是的毫无意义的,因为我们可能已经禁用例外,所以这是来检查故障的内存的唯一途径ALLOC,等等。

*- Aha! So checking to see if new D3DClass wasn't pointless, as we've probably disabled exceptions so this is the only way to check for failed memory alloc, among other things.

这篇关于什么是落后两步对象毁灭的理由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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