1

foo というオブジェクトのリストがあるとします。最初の foo が作成されたときにメンバー init() が一度だけ呼び出されるようにするにはどうすればよいですか。また、最後のオブジェクトが破棄されたときにメンバー quit() が呼び出されるのは1回だけであることを確認するにはどうすればよいですか。

私は、c++1 には std::call_once があり、c++03 には 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 ++機能に頼るだけでこれを正しくする方法はありますか?

ここで、私が実際にやろうとしていることへの小さな追加があります。C++ クラス内で SDL ウィンドウをラップしようとしていて、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 に答える