boost shared_ptr, weak_ptr

头文件

点击(此处)折叠或打开

#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>

简单使用

点击(此处)折叠或打开

int main()
{
    boost::shared_ptr<string> sp(new string("aaa")); // 构造函数接受一个new出来的指针
    cout << "ref count " << sp.use_count() << endl; // 引用计数
    cout << "exclude " << sp.unique() << endl; // 指针是否被自己独占
    {
        boost::shared_ptr<string> sp2 = sp; // 赋值的时候,引用计数会增加

        // sp和sp2都能看到引用计数,unique()返回false
        cout << "ref count " << sp.use_count() << endl;
        cout << "exclude " << sp.unique() << endl;
        cout << "ref count " << sp2.use_count() << endl;
        cout << "exclude " << sp2.unique() << endl;

        // 可以通过任意指向这个字符串对象的shared_ptr操作字符串对象
        // 支持 ->* 操作符来模拟普通指针
        sp2->append("xxx");
    }
    // sp2的作用于至于大括号,大括号结束后,引用计数减小1,unique()有返回ture了
    cout << "ref count " << sp.use_count() << endl;
    cout << "exclude " << sp.unique() << endl;

    cout << *sp << endl;

    // 最后sp会析构,最后一个析构的shared_ptr会自动delete 指向的对象。
    return 0;
}

可以用make_shared来去掉显示new,这样new和delete都被隐藏了。

点击(此处)折叠或打开

boost::shared_ptr<string> sp = boost::make_shared<string>("aaa");

不仅仅直接赋值,任何拷贝shared_ptr的行为都会增加引用计数

点击(此处)折叠或打开

boost::shared_ptr<string> func(boost::shared_ptr<string> s)
{
    cout << "in func ref count " << s.use_count() << endl; // 参数拷贝后引用计数变成2
    return s;
}

int main()
{
    boost::shared_ptr<string> sp = boost::make_shared<string>("aaa");
    cout << "ref count " << sp.use_count() << endl; // 刚开始引用计数是1
    boost::shared_ptr<string> sp2 = func(sp); // 退出函数后,参数被析构了,引用计数变成1,但是返回值又让引用计数升到2
    cout << "ref count " << sp.use_count() << endl;
    sp2.reset(); // sp2释放对象
    cout << "ref count " << sp.use_count() << endl; // 引用计数变回1
    return 0;
}

[root@server2 test]# ./a
ref count 1
in func ref count 2
ref count 2
ref count 1

另一种隐含增加引用计数的情况

点击(此处)折叠或打开

int main()
{
    vector<boost::shared_ptr<int> > v;
    {
        int i;
        for(i=0; i<10; i++)
        {
            v.push_back(boost::make_shared<int>(i));
        }
    }
    
    //由于stl容器的元素是拷贝进去的,因此shared_ptr维护的对象也不会被销毁
    cout << v[5].use_count() << endl;
    return 0;
}

weak_ptr可以用来监控shared_ptr,但是不会影响引用计数

点击(此处)折叠或打开

boost::shared_ptr<int> sp1 = boost::make_shared<int>(100);
    cout << "ref count " << sp1.use_count() << endl;
    boost::weak_ptr<int> wp1(sp1);
    boost::weak_ptr<int> wp2 = sp1;
    boost::weak_ptr<int> wp3 = wp2;
    // 虽然定义了3个weak_ptr,但是引用计数没有改变,从weak_ptr里可以取出shared_ptr的引用计数
    cout << "ref count " << sp1.use_count() << endl;
    cout << "ref count " << wp1.use_count() << endl;
    cout << "ref count " << wp2.use_count() << endl;
    cout << "ref count " << wp3.use_count() << endl;
    cout << endl;

    //创建新的shared_ptr
    boost::shared_ptr<int> sp2 = sp1;
    boost::shared_ptr<int> sp3 = wp1.lock(); // 可以从weak_ptr生成shared_ptr
    cout << "ref count " << sp1.use_count() << endl;
    cout << "ref count " << wp1.use_count() << endl;
    cout << "ref count " << wp2.use_count() << endl;
    cout << "ref count " << wp3.use_count() << endl;
    cout << endl;
    sp1.reset();
    sp2.reset();
    sp3.reset();

    // shared_ptr销毁资源后,从weak_ptr可以查看状态wp1.expired()
    cout << "ref count " << wp1.use_count() << endl;
    cout << "expired " << wp1.expired() << endl;


[root@server2 test]# ./a
ref count 1
ref count 1
ref count 1
ref count 1
ref count 1

ref count 3
ref count 3
ref count 3
ref count 3

ref count 0
expired 1

析构

点击(此处)折叠或打开

int main()
{
    int* i = new int(100);
    {
        boost::shared_ptr<int> sp1(i);
    }
    // 在大括号里把i交给shared_ptr管理了,大括号结束后,由于引用计数变成0,shared_ptr在析构的同时执行了delete i
    // 因此大括号结束后,指针i已经失效了,手工调用delete会发生core dump
    delete i;
    return 0;
}

自定义删除函数后,shared_ptr会把delete i 换成我们指定的del(i)

点击(此处)折叠或打开

void del(int* i)
{
    cout << "deleter " << *i << endl;
}

int main()
{
    int* i = new int(100);
    {
        boost::shared_ptr<int> sp1(i, del);
    }

    // 由于在del函数里只是打印了i,并没有delete i,因此指针i扔是有效的。
    delete i;
    return 0;
}

暴露this指针

点击(此处)折叠或打开

以下代码,A将this封装成shared_ptr提供给其它类
class printer;
class A: public enable_shared_from_this<A>
{
public:
    A(int i, printer* p): _i(i), _p(p){};
    int get() const { return _i; };
    void print();
private:
    int _i;
    printer* _p;
    shared_ptr<A> get_this() { return shared_from_this();};
};

class printer
{
public:
    void print(shared_ptr<A> a) { cout << a->get() << endl; }
};

void A::print() {_p->print(get_this()); }

int main()
{
    printer p;
    shared_ptr<A> a = make_shared<A>(100, &p);
    a->print();
    return 0;
}

















来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2125591/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26239116/viewspace-2125591/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值