weak_ptr和intrusive_ptr

1、weak_ptr

(1)、weak_ptr是为了配合shared_ptr而引入的智能指针,它更像是shared_ptr的一个助手,它不具有普通指针的行为,

没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。

(2)、2个重要接口:bool expired()const ;// 判断是否过期

lock()函数是弱指针的核心;

(3)、获得资源的观测权,但weak_ptr没有共享资源,它的构造不会引起引用计数的增加,它的析构也不会导致引用计数减少,

它只是一个静静的观察者。

2、使用weak_ptr

调用系统库的:

#include<iostream>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;

int main(void){
    int *p = new int(10);
    shared_ptr<int> sp(p);
    
    weak_ptr<int> wp(sp);//1、本身对wp的创建与析构是不会增加/减少use_count;
    cout<<wp.use_count()<<endl;//2、显示的是它所观测对象的引用计数器

    if(!wp.expired()){  //没过期(use_count != 0,空间还没释放)
        shared_ptr<int> sp1 = wp.lock();
        //3、wp的lock()函数在有效的前提下可以构造对象(构造的是所观测的对象)。
        //使use_count加1;
    }//失效的话,构建的是一个空对象,引用计数将不会在增加!!!

}

3、weak_ptr源码剖析

结合shared_ptr和前面的所有,删除器,shared_array、weak_ptr给出模拟的部分代码:

模仿源代码,写出了最重要的函数:

#ifndef _CONFIG_H_
#define _CONFIG_H_

#include<iostream>
using namespace std;

//#define DISPLAY

#endif
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_PTR_H_
#define _SHARED_PTR_H_

#include"shared_count.h"

template<class T>
class weak_ptr;

template<class T>
class shared_ptr{
    friend class weak_ptr<T>;
    typedef shared_ptr<T> this_type;
public:
    template<class Y, class D>
        shared_ptr(Y *p, D d) : px(p), pn(p, d){}//支持传递删除器
    shared_ptr(T *p = 0) : px(p), pn(p){
#ifdef DISPLAY
        cout<<"Create shared_ptr object!"<<endl;
#endif
    }
    shared_ptr(shared_ptr<T> const &r) : px(r.px), pn(r.pn){}
    shared_ptr<T>& operator=(shared_ptr<T> const &r){
        if(this != &r){
            this_type(r).swap(*this);//调用拷贝构造,先创建一个无名临时的对象
        }
        return *this;
    }
    ~shared_ptr(){
#ifdef DISPLAY
        cout<<"Free shared_ptr object"<<endl;
#endif
    }
public:
    T& operator*()const{
        return *(get());
    }
    T* operator->()const{
        return get();
    }
    T* get()const{
        return px;
    }
public:
    long use_count()const{
        return pn.use_count();
    }
    bool unique()const{
        return pn.unique();
    }
    void reset(T *p){
        this_type(p).swap(*this);
    }
    void swap(shared_ptr<T> &other){
        std::swap(px, other.px); //指针的交换
        pn.swap(other.pn);
    }
public:
    template<class Y>
    shared_ptr(weak_ptr<Y> const &r) : pn(r.pn){
        px = r.px;
    }

private:
    T *px;
    shared_count pn;
};

#endif
/////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_COUNT_H_
#define _SHARED_COUNT_H_

#include"config.h"
#include"sp_counted_base.h"
#include"sp_counted_impl_xx.h"

class shared_count{
    friend class weak_count;
public:
    template<class T>  //此时类型不定,写模板函数
        shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){
#ifdef DISPLAY
        cout<<"Create shared_cout object!"<<endl;
#endif
    }
    template<class Y, class D>
    shared_count(Y *p, D d) : pi(0){
        typedef Y* P;
        pi = new sp_counted_impl_pd<P, D>(p, d);
    }
    shared_count(shared_count const &r) : pi(r.pi){
        if(pi){
            pi->add_ref_copy();
        }
    }
    ~shared_count(){
#ifdef DISPLAY
        cout<<"Free shared_count object"<<endl;
#endif
        if(pi){
            pi->release();
        }
    }
public:
    long use_count()const{
        return pi != 0 ? pi->use_count() : 0;
    }
    bool unique()const{
        return use_count() == 1;
    }
    void swap(shared_count &r){
        sp_counted_base *tmp = r.pi;
        r.pi = pi;
        pi = tmp;
    }
public:
    explicit shared_count(weak_count const &r);
private:
    sp_counted_base *pi;
};
/////////////////////////////////////////////////////
template<class P, class D>
class sp_counted_impl_pd : public sp_counted_base{
public:
    sp_counted_impl_pd(P p, D d) : ptr(p), del(d){}
public:
    void dispose(){
        del(ptr);
    }
private:
    P ptr;
    D del;
};
/////////////////////////////////////////////////////////////////////
class weak_count{
    friend class shared_count;
public:
    weak_count(shared_count const &r) : pi(r.pi){
        if(pi != 0){
            pi->weak_add_ref();
        }
    }
    ~weak_count(){
        if(pi){
            pi->weak_release();
        }
    }
public:
    long use_count()const{
        return pi != 0 ? pi->use_count() : 0;
    }
private:
    sp_counted_base *pi;
};

shared_count::shared_count(weak_count const &r) : pi(r.pi){
    if(pi){
        pi->add_ref_lock();
    }
}
#endif
//////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_BASE_H_
#define SP_COUNTED_BASE_H_

#include"config.h"

class sp_counted_base{  //抽象类
public:
    sp_counted_base() : use_count_(1), weak_count_(1){
#ifdef DISPLAY
        cout<<"Create sp_counted_base object"<<endl;
#endif
    }
    virtual ~sp_counted_base(){
#ifdef DISPLAY
        cout<<"Free sp_counted_base object"<<endl;
#endif
    }
public:
    virtual void dispose() = 0; //纯虚函数
    void release(){
        if(--use_count_ == 0){
            dispose();
            delete this;
        }    
    }
public:
    long use_count()const{
        return use_count_;
    }
    void add_ref_copy(){
        ++use_count_;
    }
    void weak_add_ref(){
        ++weak_count_;
    }
    virtual void destroy(){
        delete this;
    }
    void weak_release(){
        if(--weak_count_ == 0){
            destroy();
        }
    }
    bool add_ref_lock(){
        if(use_count == 0){
            return false;
        }
        ++use_count_;
        return true;
    }
private:
    long use_count_;
    long weak_count_;
};

#endif
/////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_ARRAY_H_
#define _SHARED_ARRAY_H_

#include"checked_delete.h"

template<class T>
class shared_array{
public:
    typedef checked_array_deleter<T> deleter;
    shared_array(T *p = 0) : px(p), pn(p, deleter()){} //无名对象
    ~shared_array(){
        
    }
public:
    T& operator[](int i)const{
        return px[i];
    }
private:
    T *px;
    shared_count pn;  //必须用到引用计数器对象
};

#endif
////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _CHECKED_DELETE_H_
#define _CHECKED_DELETE_H_

template<class T>
void checked_array_delete(T *x){
    delete []x;
}

template<class T>
struct checked_array_deleter{
public:
    void operator()(T *x)const{
        checked_array_delete(x);        
    }
};

#endif
//////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _WEAK_PTR_H_
#define _WEAK_PTR_H_

#include"shared_ptr.h"

template<class T>
class shared_ptr;

class shared_count;
template<class T>
class weak_ptr{
    friend class shared_ptr<T>;
    friend class shared_count;
public:
    template<class Y>
    weak_ptr(shared_ptr<Y> const &r) : px(r.px), pn(r.pn){}
    ~weak_ptr(){}
public:
    long use_count()const{
        pn.use_count();
    }
    bool expired()const{
        return pn.use_count() == 0;
    }
    shared_ptr<T> lock()const{
        return shared_ptr<T>(*this);
    }
private:
    T *px;
    weak_count pn;
};

#endif
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_IMPL_XX_H_
#define SP_COUNTED_IMPL_XX_H_

#include"sp_counted_base.h"

template<class T>
class sp_counted_impl_xx : public sp_counted_base{
public:
    sp_counted_impl_xx(T *p) : px_(p){
#ifdef DISPLAY
        cout<<"Create sp_counted_impl_xx object"<<endl;
#endif
    }
    ~sp_counted_impl_xx(){
#ifdef DISPLAY
        cout<<"Free sp_counted_impl_xx object"<<endl;
#endif
    }
public:
    void dispose(){
        delete px_;
    }
private:
    T *px_;
};

#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include"shared_ptr.h"
#include"shared_array.h"
#include"weak_ptr.h"
using namespace std;

int main(void){
    int *p = new int(10);

    shared_ptr<int> sp(p);
    weak_ptr<int> wp(sp);
    if(!wp.expired()){
        shared_ptr<int> sp1 = wp.lock();//返回真实的对象
        cout<<sp.use_count()<<endl;
    }
    cout<<sp.use_count()<<endl;

}

这是这个智能指针的最主要的剖析,关键理清脉络,条理清晰一些,就可以分析出来!

4、intrusive_ptr的使用

适用情景:(1)、对内存的占用要求非常严格,不能有引用计数的内存开销;

(2)、这时的代码中已经有了引用计数机制管理的对象;

重点掌握如何使用:

(1)、两个方法必须重写(增加/减少引用计数)

(2)、必须自己编写管理引用计数的类

(3)、要封装到一个类中,在继承(把自己的类侵入到智能指针中进行管理)

具体使用的一个类子如下:

#include<iostream>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;
 
//1、实现2个重要的函数
template<class T>
void intrusive_ptr_add_ref(T *t){ //增加引用计数
    t->add_ref_copy();
}
template<class T>
void intrusive_ptr_release(T *t){  //减少引用计数
    t->release();
}

//2、提供管理对象
class Counter{
public:
    Counter() : use_count_(0){
    
    }
    ~Counter(){
    
    }
public:
    void add_ref_copy(){
        ++use_count_;
    }
    void release(){
        if(--use_count_ == 0){
            delete this;
        }
    }
private:
    long use_count_;
};
//3、定义自己的对象
class Test;
ostream& operator<<(ostream &out, const Test &t);
class Test : public Counter{
    friend     ostream& operator<<(ostream &out, const Test &t);
public:
    Test(int d = 0) : data(d){}
    ~Test(){}
private:
    int data;
};

ostream& operator<<(ostream &out, const Test &t){
    out<<t.data;
    return out;
}

int main(void){
    Test *pt = new Test(10);
    intrusive_ptr<Test> ip(pt);
    cout<<*ip<<endl;

}

结果如下:

时间: 2024-08-08 15:53:05

weak_ptr和intrusive_ptr的相关文章

智能指针学习笔记

1. 介绍 本文介绍智能指针的使用.智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将c++ 程序员 从指针和内存管理中解脱出来,再者,这也是c++发展的趋势(这话不是我说的,见<Effective c++>和<c++实践编程>),应该认真学习一下. 智能指针中,最有名的应该数auto_ptr,该智能指针已经被纳入标准库,只需要包含<memory>头文件即可以使用,另外,TR1文档定义的shared_ptr和weak_ptr也已经实现(我用

Boost源码学习---weak_ptr.hpp

weak_ptr是辅助shared_ptr的智能指针.就像它的名字一样,是个"弱"指针:仅有几个接口,仅能完成很少工作.它可以从一个shared_ptr或weak_ptr对象构造,获取对资源的观测权,它是没有共享资源的,所以它的对象的创建不会引起指针引用计数的增加,它的对象的析构也不会引起计数器的减少. 它没有重载*和->,不能使用指针,主要的几个接口如下: long use_count() const//返回计数器数值 bool expired() const//判断指针是否失

weak_ptr打破环状引用

转自:http://blog.csdn.net/malong777/article/details/48974559 weak_ptr是一种不控制对象生存周期的智能指针,它指向一个shared_ptr管理的对象...它不会改变shared_ptr的引用计数--<C++ Primer .5th>.很明显,weak_ptr的特点是"弱引用".有什么用?应用场景是什么地方? 考虑它的胞兄shared_ptr,每次复制之后引用计数加一,不再指向对象(自身销毁或指向其他对象)时时引用

#include &lt;boost/weak_ptr.hpp&gt;

弱指针boost::weak_ptr的定义在boost/weak_ptr.hpp里.到目前为止介绍的各种智能指针都能在不同的场合下独立使用.相反,弱指针只有在配合共享指针一起使用时才有意义.因此弱指针被看作是共享指针的观察者,用来观察共享指针的使用情况.当用到共享指针时,就要考虑是否需要使用弱指针了,这样可以解除一些环形依赖问题. 1 #include <iostream> 2 #include <windows.h> 3 #include <boost/weak_ptr.h

C++ 11 创建和使用共享 weak_ptr

有时对象必须存储一种方法,用来在不引起引用计数增加的情况下访问 shared_ptr 的基础对象.通常,当您在 shared_ptr 实例之间循环引用时,就会出现此情况. 最佳的设计能够尽可能地避免指针具有共享所有权.但是,如果您必须具有共享的 shared_ptr 实例所有权,请避免在实例之间进行循环引用.如果循环引用不可避免,甚至由于某种原因而更为可取,请使用 weak_ptr 为一个或多个所有者提供对其他 shared_ptr 的弱引用.使用 weak_ptr,您可以创建连接到现有相关实例

shared_ptr与weak_ptr的例子

12.20 编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob的每个元素. StrBlob.h #ifndef STRBLOB_H #define STRBLOB_H #include<iostream> #include<string> #include<vector> #include<memory> using namespace std; class StrBlobPtr; class St

std::weak_ptr 每次 lock() 都会导致自身use_count自增一次

代码: #include <memory> #include <iostream> int main(int argc, char*argv[]){ std::shared_ptr<int> a(new int(1)); std::weak_ptr<int>d(a); std::cout<<"d.use_count() = "<<d.use_count()<<std::endl; std::cout&l

weak_ptr

#include <iostream> #include <memory> using namespace std; int main(int argc, char **argv) { // shared_ptr<int> sp(new int(10)); shared_ptr<int> sp = make_shared<int>(10); cout << sp.use_count() << " " &

boost智能指针之shared_ptr和weak_ptr

std::auto_ptr很多的时候并不能满足我们的要求,比如auto_ptr不能用作STL容器的元素.boost的smart_ptr中提供了4种智能指针和2种智能指针数组来作为std::auto_ptr的补充. shared_ptr<boost/shared_ptr.hpp>:使用shared_ptr进行对象的生存期自动管理,使得分享资源所有权变得有效且安全. weak_ptr<boost/weak_ptr.hpp>:weak_ptr 是 shared_ptr 的观察员.它不会干