C++中的智能指针 smart_ptr

C++ 中需要自己来处理内存,稍微处理不当,就会存在非常郁闷的内存泄漏问题

 

还好,现在 C++ 中推出了强大的智能指针,即 smart_ptr ,本文先稍微介绍一下 smart_ptr ,然后具体说说 shared_ptr weak_ptr ,特别是 enable_shared_from_this shared_from_this

 

除了标准库中的 auto_ptr 之外

boost 或者 tr1 中的 smart_ptr 主要是有下面几种

  • scoped_ptr
  • scoped_array
  • shared_ptr
  • shared_array
  • intrusive_ptr
  • weak_ptr

这些里面最难理解的是综合应用了 weak_ptr shared_ptr enable_shared_from_this 类,在该类中定了成员函数 shared_from_this() ,返回 shared_ptr<T> 。这个函数仅在 shared_ptr<T> 的构造函数被调用之后才能使用。原因是 enable_shared_from_this::weak_ptr 并不在构造函数中设置(此处的构造函数指的是类型 T 的构造函数),而是在 shared_ptr<T> 的构造函数中设置(此处的构造函数指的是类型 shared_ptr<T> 的构造函数)。

 

在下面的代码中:

 

#include <iostream>

#include <string>

 

#include <boost/shared_ptr.hpp>

#include <boost/weak_ptr.hpp>

#include <boost/enable_shared_from_this.hpp>

 

using namespace std;

 

struct Ansible

  : public boost::enable_shared_from_this<Ansible>

{

    boost::shared_ptr<Ansible> get_shared()

    {

        boost::shared_ptr<Ansible> r(this);

 

        return r;

    }

 

    ~Ansible()

    {

        cout<<"Destructor"<<endl;

    }

};

 

int main(int argc,char* argv[])

{

    boost::shared_ptr<Ansible> a(new Ansible);

    Ansible& r = *a;

    //boost::shared_ptr<Ansible> b = r.get_shared();

    boost::shared_ptr<Ansible> b = r.shared_from_this();

 

    cout<<"Reference Number "<<a.use_count()<<" "<<b.use_count()<<endl;

 

    return 0;

}

 

若不使用 shared_from_this() 成员函数,则会输出 a b use_count() 都为 1 ,然后调用 2 次类型 Ansible 的析构函数,若添加了该成员函数,在 a b use_count() 输出为 2 ,只是调用一次 Ansible 的析构函数。原因是 enable_shared_from_this 里面在 shared_ptr<T> 的时候构造了一个 weak_ptr 类,而 weak_ptr 只是监视,不增加引用计数

 

(下面是转载: http://huyuguang1976.spaces.live.com/blog/cns!2A9E272E3C33AFF1!185.entry

所以如下代码是错误的:

 

class D:public boost::enable_shared_from_this<D>

{

public:

    D()

    {

        boost::shared_ptr<D> p=shared_from_this();

    }

};

 

原因很简单,在 D 的构造函数中虽然可以保证 enable_shared_from_this<D> 的构造函数已经被调用,但正如前面所说, weak_ptr 还没有设置。

 

如下代码也是错误的:

 

class D:public boost::enable_shared_from_this<D>

{

public:

    void func()

    {

        boost::shared_ptr<D> p=shared_from_this();

    }

};

 

void main()

{

    D d;

    d.func();

}

 

错误原因同上。

 

如下代码是正确的:

 

void main()

{

    boost::shared_ptr<D> d(new D);

    d->func();

}

 

这里 boost::shared_ptr<D> d(new D) 实际上执行了 3 个动作:首先调用 enable_shared_from_this<D> 的构造函数;其次调用 D 的构造函数;最后调用 shared_ptr<D> 的构造函数。是第 3 个动作设置了 enable_shared_from_this<D> weak_ptr ,而不是第 1 个动作。这个地方是很违背 c++ 常理和逻辑的,必须小心。

 

结论是,不要在构造函数中使用 shared_from_this ;其次,如果要使用 shared_ptr ,则应该在所有地方均使用,不能使用 D d 这种方式,也决不要传递裸指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值