4

这是代码,它非常简单。

class Foo
{
public:
    void print()
    {
        std::cout<<"Foo::print\n";
    }
}; 


Game::Game()
{
    {
        Foo foo;
        player.onclick = bind(&Foo::print,foo);

    }
    player.onclick();
}

内部作用域完成后, foo 对象超出作用域,但 print 方法仍然被调用,我猜这是因为 player 持有对 foo 对象的引用?有没有办法阻止这种情况发生?我不希望对象在应该被销毁时保持活动状态并接收事件。

谢谢。

4

3 回答 3

6

您已绑定到foo; 该副本的持续时间与绑定的函数对象一样长,而原始副本foo在其范围结束时被销毁。

如果您不想让它保持活动状态,则绑定到指针 ( &foo) 或引用 ( std::ref(foo));然后你必须小心,一旦foo超出范围就不要调用函数对象。请注意,无法从函数对象中看出这已经发生了;调用它会给出未定义的行为。

为了在对象被销毁时安全地断开它,您必须安排其析构函数重新分配onclick,或者让其他对象负责首先重新分配onclick,然后销毁该对象。

于 2012-04-04T19:59:26.447 回答
0

我认为你应该shared_ptr在分配Footo时使用Player,并保持 a weak_ptrto Fooin Player。然后尝试锁定功能weak_ptronclick看看是否Foo还活着。像这样的东西:

using namespace std;
class Foo
{
    public:
        void print()
        {
            cout<<"Foo::print\n";
        }
}; 

class Player
{
    public:
        weak_ptr<function<void()>> _onClickFuntion;
        void onclick()
        {
            shared_ptr<function<void()>> tempFunction(_onClickFunction.lock());
            if (tempFunction)
                tempFunction();
        }
}

Game::Game()
{
    {
        Foo foo;
        player._onClickFuntion = shared_ptr<function<void()>>(new bind(&Foo::print,foo));
    }
    player.onclick();
}
于 2012-05-11T13:45:52.050 回答
0

根据您的描述,听起来您实际上想要一个事件循环。虽然std::bind对类似的东西很有用,但它本身并不是一个整体。我建议你看看boost.signals

于 2012-04-04T20:03:04.807 回答