1

假设我有一个名为 foo 的对象列表。我如何确保在创建第一个 foo 时调用成员 init() 但只调用一次。另外我如何确保当最后一个对象被销毁时,成员 quit() 被调用但只调用一次。

我知道 c++11 有 std::call_once,而对于 c++03,boost 有 boost::call_once。

我的第一次尝试看起来像这样,但退出部分显然是错误的:

class foo
{
public:

    foo() { init(); }

    ~foo() 
    {
        // this is wrong
        quit();
    }

private:

    void init()
    {
        static boost::once_flag flag = BOOST_ONCE_INIT;
        boost::call_once( flag, [] () { /* init something */ }  );
    }

    void quit()
    {
        static boost::once_flag flag = BOOST_ONCE_INIT;
        boost::call_once( flag, [] () { /* quit something */ } );
    }
};

有没有办法仅依靠 c++ 工具来使其正确?

这是我实际尝试做的一个小补充。我正在尝试将 SDL 窗口包装在 c++ 类中,并希望调用 SDL_Init() 和 SDL_Quit 以及适当的时间。我的第一次尝试在这里: http: //pastebin.com/Y9X0UwUB

4

3 回答 3

3

听起来您希望这些方法成为static,然后还维护活动对象数量的私有静态计数,该计数在构造函数和析构函数中递增/递减并检查。

显然,如果这是一个多线程应用程序,您将需要某种形式的同步。

于 2013-03-06T22:48:44.030 回答
0

您可以创建一个新类,在构造时调用 init 函数,在销毁时调用 quit 函数,然后让类的所有实例在构造时接收到该类实例的 shared_ptr。

class foo_init_quit {
    public:
      foo_init_quit(){init();}
      ~foo_init_quit(){quit();}
};

std::vector<foo> do_something() {
    auto init_quit = make_shared<foo_init_quit>();
    std::vector<foo> vec;
    vec.emplace_back(init_quit);
    //...
    return vec;
}
于 2013-03-06T22:49:38.930 回答
0
struct Funkay
{
    Funkay() : { ++count; init(); }
    ~Funkay() { --count; quit(); }

private:
    static size_t count;
    void init() { if (count == 1) ???; }
    void quit() { if (count == 0) ???; }
};
size_t Funkay::count = 0;
于 2013-03-06T23:01:26.780 回答