shared_ptr相关小结

程序中,有些对象的生命周期是静态的可预测的,这时只要把构造销毁的时机硬编码进程序即可;然而有些对象的生命周期却和运行时环境相关(例如在线程间共享对象,无“引用”时销毁),对于这种类型的对象必须借助额外的信息和设施来控制,基于引用计数的封装boost::shared_ptr及其相关设施就是其中一种(我所了解的还有基于标记-清除的GC),下面就易错的地方小结下:

  1. 一般而言,不要同时使用boost::shared_ptr和其他的管理机制来管理对象的生命周期,这样会发生语义上的矛盾,极有可能出现运行时错误。
  2. 切记保持boost::shared_ptr在程序各处的ownership语义,特别是对于线程函数以boost::shared_ptr持有某对象ownership的情况,必须保证在进入线程函数前完成引用计数的自增;因此,不进行有关ownership语义的的自增操作(一般而言,即以值语义直接传递boost::shared_ptr本身),而以指向或间接指向boost::shared_ptr的指针或引用作为线程函数的参数传递多数情况下都是畸形的语义,极有可能出现空指向的运行时错误,除非线程函数及其后继并不对boost::shared_ptr以及其指向对象作任何操作(这种情况下的传递是多余的)。
  3. 由于boost::shared_ptr享有所管理对象的ownership,因此一般来说对象不能享有指向自身的boost::shared_ptr对象的ownership;否则它们的销毁时机会形成彼此依赖的局面。
  4. 在一个对象的生命周期内,不要尝试多次从指向对象的原始指针构造boost::shared_ptr,这样会使每个boost::shared_ptr各自维护一个引用计数,造成对象的多次销毁;因此,在成员函数内使用this指针构造boost::shared_ptr基本上都是错误的,正确的方法是使此对象的类型继承boost::enable_shared_from_this,并调用成员函数shared_from_this得到boost::shared_ptr
  5. 对于继承于boost::enable_shared_from_this模板的类型,调用成员函数shared_from_this之前必须确保至少存在一个指向此类型对象的boost::shared_ptr实例,这是因为boost::enable_shared_from_this拥有一个boost::weak_ptr成员(为了避免第3项循环引用的情况),而boost::weak_ptr对象必须通过另一个boost::weak_ptrboost::shared_ptr来初始化。
  6. 由第5项可知:当类的某些成员需要以指向此类对象的boost::shared_ptr初始化时,不要尝试在构造函数中使用成员函数shared_from_this,此时并不能保证boost::shared_ptr的实例已经存在;取而代之,只能使用二段初始化流程,在构造函数之外对这些成员进行初始化;然而由于使用了shared_from_this,根据第1项,必须强制以boost::shared_ptr来管理此类对象的生命周期,也就是说,在构造函数返回时,必须立刻以其返回指针构造一个boost::shared_ptr;因此最好看以及最保险的方法是用一个静态初始化式(以指向此类对象的boost::shared_ptr作为返回值)包裹起二段初始化流程,隐藏实现。
  7. boost::shared_ptr本身对于同时读操作是线程安全的,同时写以及同时读写操作都不是线程安全的。
  8. boost::shared_ptr不改变其管理对象的线程安全级别。

你可能感兴趣的:(shared_ptr相关小结)