如何确保成员函数只被调用一次

How to make sure a member function is called once

本文关键字:调用 一次 成员 何确保 确保 函数      更新时间:2023-10-16

假设我有一个名为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

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

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

您可以创建一个新类,在构造时调用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;
}
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;