boost::bind对引用的特殊处理

最近使用boost::bind比较多,发现有一些奇怪的现象。就是在用boost::bind传递引用的时候,如果引用的对象被释放,那么之后的函数执行必然会访问无效的地址儿出错。但是这个担忧是多余的,boost::bind在传递引用的时候,并不是真的传递引用,而是执行对象的拷贝构造函数重新生成了一个全新的对象,测试代码如下:

#include<iostream>
  #include <boost/bind.hpp>
  #include <boost/function.hpp>
  using namespace std;
  
  class A
  {
      public:
          A(){ i = 0; cout << "A constructor" << endl;}
          A(const A& a)
          {
              i = 0;
          cout << "A copay constructor" << endl;
          }
          int i;
  };
  
  typedef boost::function<void (void)> fun;
  
  void myfun(A& a)
  {
      a.i += 10;           
  }
  
int main(int argc, char** argv)
  {
      A a;    
      a.i = 0;
      fun f(boost::bind(myfun, a));
      f();    
      cout << a.i << endl;//此处输出0,而不是期望的10
      return 0;
  }

输出结果如下:

A constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
A copay constructor
0
可以看到,A类的构造函数被调用了很多次,这个我也不是很清楚内部的实现逻辑,但是可以清楚的是引用传递没有生效,实际上是生成了一个新的对象。再对新的对象的i进行加10,所以打印出的a对象的i实际上并没有被改变,为0;

这个设计我猜想boost设计者的原意也是担心引用对象被释放,造成引用无效对象而崩溃的问题,因此在传递引用的时候实际上是值传递。

如果真的想传递引用,也是有办法的,boost设计者给了boost::ref这个对象,明确表示我只传递引用,不要拷贝。以上代码可以改成:

fun f(boost::bind(myfun, boost::ref(a)));

更改之后输出为:

A constructor
10

这个就不会重新生成很多对象了,从始至终都只有一个对象

如果明确了引用对象不会被释放,建议使用boost::ref来强制避免拷贝,毕竟那么多对象的构造和析构都是对性能的浪费,也增加了出错的可能性。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值