boost :: bind内部副本/副本?

时间:2012-03-14 15:21:05

标签: c++ boost bind internals

我希望了解boost :: bind做什么样的函数对象内部副本。由于这些对象的构造函数似乎没有被调用,我认为这是一种“非常浅的副本”,所以我引入了动态内存分配来产生一些错误。但是,下面代码的运行时输出似乎表明三个对于由bind生成的内部副本的其他析构函数调用。

using namespace std;
using namespace boost;

class M{
    int *somedata;
public:
    M(){ somedata=new int[5]; cout<<"from cstr\n"; somedata[1]=0;}
    ~M(){cout<<"from dstr\n"; delete somedata;}

    int operator()(int i){ cout<<++somedata[i]<<endl; return 0;}
};


int main()
{
    M instM;

    bind<int>(instM,1)();
    //bind<int>(&M::operator(),&instM,1)(); //this works with no errors, of course

    instM(1); //would not change the order of output

    return 0;
}

输出......提供了一些额外的谜题 - 例如。为什么第一个dstr事件在调用operator()之前出现?在最后一次失败的析构函数调用之前还要注意“2”。

from cstr
from dstr
1
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug
2
from dstr
bind_copy(73365) malloc: *** error for object 0x1001b0: double free
*** set a breakpoint in malloc_error_break to debug

所以问题是:任何人都可以简单地解释一下这个顺序,以及哪种副本可以绑定吗?

...经过一番思考后,我意识到bind只是使用(这里是默认的)复制构造函数。在提供了这个cstr的一些自定义版本(带有内存分配和as-deep-as-one-wish许可版本的副本)后,输出变得干净(应该如此),但谜题仍然存在:有复制构造函数的调用。 所以在这种情况下,boost :: bind会生成三个的函数对象副本。为什么以及以何种顺序?(对于嵌套的boost :: binds,这会导致内部副本数量的爆炸性增长。)

定义了cp-cstr的输出,并添加了一些“遗产标记”(“P”=父,每个cp cstr添加“-C”):

 from cstr P
 from cp cstr P-C
 from cp cstr P-C-C
 from cp cstr P-C-C-C
 from dstr P-C-C
 P-C-C-C:1
 from dstr P-C-C-C
 from dstr P-C
 P:1
 from dstr P

1 个答案:

答案 0 :(得分:2)

请参阅here

  

默认情况下,bind会复制提供的函数对象。 boost :: ref和boost :: cref可用于使其存储对函数对象的引用,而不是副本。当函数对象不可复制,复制昂贵或包含状态时,这可能很有用;当然,在这种情况下,程序员应该确保函数对象在被使用时不被破坏。