如何指定析构函数的调用顺序?

时间:2013-08-31 16:30:43

标签: c++ sdl

我想用SDL 2.0编写一个简单的游戏,它的结构看起来像这样:

  • 类Engine,它将在其构造函数中初始化SDL(SDL.Init()),在析构函数中调用SDL_Quit(),并包含Window和Texture的实例
  • class Texture - SDL_Texture *的包装类。在创建时创建纹理,在析构函数中销毁纹理
  • class Window - SDL_Window的包装类,在开始时创建SDL_Window *和SDL_Renderer *,在析构函数中删除。

现在,据我所知,SDL_Quit()卸载dll,关闭所有子系统等。如果我理解正确,那么如果我调用SDL_Quit(),调用SDL_DestroyWindow(),SDL_DestroyRenderer()和SDL_DestroyTexture()可能没有影响或导致错误,因为系统已被卸载以及dll。

因此,在调用SDL_Quit()之前,我希望在Engine的析构函数的开始时销毁Engine内的Texture和Window。

当我尝试在一个简单的类示例上模拟它时,我得到了简单的LIFO响应:

  

初始化ClassOne对象

     

ClassTwo对象初始化

     

初始化聚合对象

     

销毁聚合对象

     

ClassTwo对象被破坏

     

ClassOne对象被破坏

这不是我想要的。我设法使用指针和动态内存分配来解决我的问题。我只是在Aggregate的构造函数中使用operator new创建它们,并使用析构函数中的operator delete销毁它们。

但是,还有其他方法可以做到这一点,不涉及指针吗? 提前谢谢。

2 个答案:

答案 0 :(得分:2)

不涉及指针:

如果你有(假设#include <iostream>

class Window {
public:
    Window() { std::cout << "W "; }
    ~Window() { std::cout << "~W "; }
};

class Texture {
public:
    Texture() { std::cout << "T "; }
    ~Texture() { std::cout << "~T "; }
};

并且您想要一个与输出Init W T~T ~W Quit对应的订单,而不是:

class Engine {
public:
    Engine() { std::cout << "Init "; }
    ~Engine() { std::cout << "Quit "; }
private:
    Window w;
    Texture t;
};

W T InitQuit ~T ~W),执行此操作:

class Initializer {
public:
    Initializer() { std::cout << "Init "; }
    ~Initializer() { std::cout << "Quit "; }
};

class Engine {
public:
    Engine() { /* nothing */ }
    ~Engine() { /* nothing */ }
private:
    Initializer i;
    Window w;
    Texture t;
};

答案 1 :(得分:1)

如果您正确订购课程,您将获得所需的销毁订单:

在课堂上:

class X {
   public:
   X()
   // This order is not relevant and should produce a compiler warning
   : ..., c(), b(), a()
   {}


   private:
   // The members are initialized in this order and destructed in the opposite order.
   A a;
   B b;
   C c
   ...
}

同样适用于单个(!)翻译单元中的静态实例:以与定义相反的顺序构造和销毁。

如果您有多个翻译单元,则不会指定每个单元的初始化顺序。在函数中包含静态数据,使其更容易 - 数据在第一个函数调用中初始化。