使用boost::bind/std::bind进行封…

来源:互联网 发布:软件被劫持 编辑:程序博客网 时间:2024/05/29 18:54
     boost::bind( ps:在c++11中被引入标准库,变成std::bind)是C++进行封包操作的利器。可以很简单地把一个函数(包括类成员函数)调用及其部分/全部参数封装成一个对象(boost::function),以供之后调用。可以理解成这是对C语言函数指针的升级,毕竟使用函数指针来进行回调,经常是用void*来指定上下文,麻烦且容易出错。
     boost::bind的实现原理是把要调用的函数和参数都保存在对象中。需要注意的是:如果参数是类和类的引用,则 boost::bind会调用拷贝构造函数把参数保存到封包中;如果是原生指针(事实上是所有原生类型,但其他如int之类不会有啥问题),则只是简单复制值。
     所以使用boost::bind的时候需要注意:
     1、如果封包参数使用类或者类的引用(两者差别不大),会调用很多次拷贝构造函数(测试代码显示居然调用超过10次),需要注意性能问题。需要确保参数类的拷贝构造函数代价较小。比如一个很大的列表类,拷贝构造函数需要运行很长时间,这种就不适合直接作为参数了。
     2、如果使用原生指针,性能是没问题了,但是需要确保对象在封包调用之前未被释放(悲剧:人还在,钱没了)。这样很容易导致野指针问题,建议如果想提高性能,应该要使用智能指针。
     下面是测试代码,测试结果是是在vs2008下跑出来的。但结论应该还是比较普适的。
=====================测试代码======================
#include <iostream>
#include <boost/bind.hpp>
#include<boost/function.hpp>
#include<boost/shared_ptr.hpp>

using namespace std;

class BindArgument
{
public:
BindArgument(int num)
{
this->num = num;
cout << "BindArgument:"<< num<< endl;
}
void foo() const
{
cout << num<< endl;
}
~BindArgument()
{
cout << "~BindArgument:"<< num<< endl;
}
BindArgument(const BindArgument& copy)
{
num = copy.num;
cout << "copy:"<< num<< endl;
}
private:
int num;
};

void testBind0(BindArgument val)
{
val.foo();
}

void testBind1(const BindArgument& val)
{
val.foo();
}

void testBind2(BindArgument* val)
{
val->foo();
}

voidtestBind3(boost::shared_ptr<BindArgument>val)
{
val->foo();
}

int main()
{
{
BindArgument* obj = new BindArgument(0);
boost::function<void (void)>func = boost::bind(&testBind0, *obj);
delete obj;
func();
}
cout <<"====================================="<< endl;
{
BindArgument* obj = new BindArgument(1);
boost::function<void (void)>func = boost::bind(&testBind1, *obj);
delete obj;
func();
}
cout <<"====================================="<< endl;
{
BindArgument* obj = new BindArgument(2);
boost::function<void (void)>func = boost::bind(&testBind2, obj);
delete obj;
func();
}
cout <<"====================================="<< endl;
{
boost::shared_ptr<BindArgument>obj(new BindArgument(3));
boost::function<void (void)>func = boost::bind(&testBind3, obj);
obj.reset();
func();
}
}
=============================测试结果=============================
BindArgument:0
copy:0
copy:0
copy:0
copy:0
~BindArgument:0
~BindArgument:0
copy:0
~BindArgument:0
~BindArgument:0
copy:0
copy:0
copy:0
copy:0
copy:0
copy:0
~BindArgument:0
~BindArgument:0
~BindArgument:0
~BindArgument:0
~BindArgument:0
~BindArgument:0
~BindArgument:0
copy:0
0
~BindArgument:0
~BindArgument:0
=====================================
BindArgument:1
copy:1
copy:1
copy:1
copy:1
~BindArgument:1
~BindArgument:1
copy:1
~BindArgument:1
~BindArgument:1
copy:1
copy:1
copy:1
copy:1
copy:1
copy:1
~BindArgument:1
~BindArgument:1
~BindArgument:1
~BindArgument:1
~BindArgument:1
~BindArgument:1
~BindArgument:1
1
~BindArgument:1
=====================================
BindArgument:2
~BindArgument:2
1133176
=====================================
BindArgument:3
3
~BindArgument:3


0 0
原创粉丝点击