您的位置:首页 > 其它

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

2015-10-10 09:23 288 查看
     
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();
}

void
testBind3(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: