在使用时删除增强功能

def*_*ode 4 c++ boost boost-bind c++11

我有一种情况,即boost :: function和boost :: bind(实际上是std :: tr1 :: function和bind)在被使用时被删除.这样安全吗?我通常会避免它,但有问题的代码有点根深蒂固,我唯一的另一个选择是添加一个新线程.

typedef function<int(int)> foo_type;

foo_type* global_foo = NULL;

int actual_foo( int i, Magic* m )
{
    delete global_foo;
    return m->magic(i);
}

int main()
{
     Magic m;
    global_foo = new foo_type( bind( &actual_foo, _1, &m );

    return (*global_foo)(10)
}
Run Code Online (Sandbox Code Playgroud)

绑定参数始终是普通的整数类型(实际代码中的int和指针),而不是引用.

Art*_*yom 5

boost::function或者std::tr1::functions是可复制的对象.所以,通常绝对没有理由分配它们 - 只是按值传递它们.

它们针对大​​多数实际案例进行了优化......所以只需按值传递它们:

typedef function<int(int)> foo_type;

foo_type global_foo;

int actual_foo( int i, Magic* m )
{
   delete global_foo;
   return m->magic(i);
}

int main()
{
   Magic m;
   global_foo = bind( &actual_foo, _1, &m );

   return global_foo(10)
}
Run Code Online (Sandbox Code Playgroud)

您建议的代码很危险,请运行以下代码:

    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    #include <iostream>
    using namespace std;

    boost::function<void()> *glb;

    struct Data {
            int x;
            Data(int _x = 0) : x(_x) { cout<<"ctor:"<<this<<endl; }
            ~Data() { cout<<"dtor:"<<this<<endl; }
            Data(Data const &p) {x=p.x; cout<<"ctor:"<<this<<endl; }
            Data const &operator=(Data const &p) { x=p.x; cout<<this<<"="<<&p<<endl; return *this; }
    };

    void func(Data const &x)
    {
            delete glb;
            cout<<&x<<endl;
    }

    int main()
    {
            glb=new boost::function<void()>(boost::bind(func,Data(3)));

            (*glb)();
            return 0;
    }
Run Code Online (Sandbox Code Playgroud)

您会发现您尝试访问已经调用的func已故对象(具有相同指针值的dtor)cout<<&x<<endl.

因为当你破坏你的功能对象时,你也会破坏你拥有的绑定参数,并且Data const &x因为它被破坏而变得不可用.global_function

编辑:清除评论:

如果你有类似的东西

map<string,function<void()> > calls;

void delete_key(){
    calls.erase("key");
}

main() 
{
     calls["key"]=delete_key;

     // Wrong and dangerous
     // You delete function while in use
     calls["key"]();

     // Correct and safe
     // You create a copy of function so it would not
     // be deleted while in use.
     function<void()> f=calls["key"];
     f();
}
Run Code Online (Sandbox Code Playgroud)