What you absolutely must know to use boost smart pointers correctly

From:http://www.codeproject.com/Articles/8394/Smart-Pointers-to-boost-your-code#

A few things can go wrong with smart pointers (most prominent is an invalid reference count, which deletes the object too early, or not at all). The boost implementation promotes safety, making all "potentially dangerous" operations explicit. So, with a few rules to remember, you are safe.

There are a few rules you should (or must) follow, though:

Rule 1: Assign and keep - Assign a newly constructed instance to a smart pointer immediately, and then keep it there. The smart pointer(s) now own the object, you must not delete it manually, nor can you take it away again. This helps to not accidentally delete an object that is still referenced by a smart pointer, or end up with an invalid reference count.

Rule 2: a _ptr<T> is not a T * - more correctly, there are no implicit conversions between a T * and a smart pointer to type T.

This means:

  • When creating a smart pointer, you explicitly have to write ..._ptr<T> myPtr(new T)
  • You cannot assign a T * to a smart pointer
  • You cannot even write ptr=NULL. Use ptr.reset() for that.
  • To retrieve the raw pointer, use ptr.get(). Of course, you must not delete this pointer, or use it after the smart pointer it comes from is destroyed, reset or reassigned. Use get() only when you have to pass the pointer to a function that expects a raw pointer.
  • You cannot pass a T * to a function that expects a _ptr<T> directly. You have to construct a smart pointer explicitly, which also makes it clear that you transfer ownership of the raw pointer to the smart pointer. (See also Rule 3.)
  • There is no generic way to find the smart pointer that "holds" a given raw pointer. However, the boost: smart pointer programming techniques illustrate solutions for many common cases.

Rule 2: No circular references - If you have two objects referencing each other through a reference counting pointer, they are never deleted. boost provides weak_ptr to break such cycles (see below).

Rule 3: no temporary shared_ptr - Do not construct temporary shared_ptr to pass them to functions, always use a named (local) variable. (This makes your code safe in case of exceptions. See the boost: shared_ptr best practices for a detailed explanation.)

Cyclic References

Reference counting is a convenient resource management mechanism, it has one fundamental drawback though: cyclic references are not freed automatically, and are hard to detect by the computer. The simplest example is this:

struct CDad;
struct CChild;

typedef boost::shared_ptr<CDad>   CDadPtr;
typedef boost::shared_ptr<CChild> CChildPtr;


struct CDad : public CSample
{
   CChildPtr myBoy;
};

struct CChild : public CSample
{
  CDadPtr myDad;
};

// a "thing" that holds a smart pointer to another "thing":

CDadPtr   parent(new CDadPtr); 
CChildPtr child(new CChildPtr);

// deliberately create a circular reference:
parent->myBoy = child; 
child->myDad = dad;


// resetting one ptr...
child.reset();


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值