c++ std::bind 保持对象存活

问题描述 投票:0回答:3

这是代码,非常简单。

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 对象的引用?有没有办法阻止这种情况发生?我不希望对象在应该被销毁的时候保持活动状态并接收事件。

谢谢。

c++ c++11
3个回答
6
投票

您已绑定

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

如果不想让它保持活动状态,则绑定到指针(

&foo
)或引用(
std::ref(foo)
);然后你必须小心,一旦
foo
超出范围,不要调用函数对象。请注意,无法从函数对象得知这已经发生了;调用它会产生未定义的行为。

为了在对象被销毁时安全地断开连接,您必须安排其析构函数重新分配

onclick
,或者让其他对象负责首先重新分配
onclick
,然后销毁该对象。


0
投票

从您的描述来看,您似乎确实想要一个事件循环。虽然

std::bind
对于类似的事情很有用,但它本身并不是一个完整的东西。我建议你看看boost.signals


0
投票

我认为当您将

shared_ptr
分配给
Foo
时,您应该使用
Player
,并在
weak_ptr
中保留
Foo
Player
。然后尝试在
weak_ptr
函数中锁定
onclick
,看看
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();
}
© www.soinside.com 2019 - 2024. All rights reserved.