weak pointer的实现方法


  1 #include  < assert.h >
  2 #include  < map >
  3 #include  < stdio.h >
  4
  5 //  memory leak checker
  6 struct  Value
  7 ExpandedBlockStart.gifContractedBlock.gif {
  8    bool valid;
  9    int line;
 10
 11    Value()
 12    :valid(false), line(-1)
 13ExpandedSubBlockStart.gifContractedSubBlock.gif    {}
 14
 15    Value(bool v, int l)
 16        :valid(v), line(l)
 17ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 18    }

 19}
;
 20
 21 typedef std::map < void * , Value >  ContainerType;
 22 ContainerType myMap;
 23
 24 #define  mynew(x) mynew_(x, __LINE__)
 25
 26 void  checkMemory()
 27 ExpandedBlockStart.gifContractedBlock.gif {
 28    size_t n = myMap.size();
 29    //assert(n==0);
 30
 31    if(n>0)
 32ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 33        printf("Memory leak found:\n");
 34        for (ContainerType::const_iterator it=myMap.begin();
 35            it!=myMap.end();++it)
 36ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 37            printf("Line %d\n", it->second.line);
 38        }

 39        assert(0);
 40    }

 41}

 42
 43 template  < class  T >
 44 T *  mynew_(T  const   & n,  int  line)
 45 ExpandedBlockStart.gifContractedBlock.gif {
 46    T* p = (T*)malloc(sizeof(T));
 47    *= n;
 48    myMap[p]=Value(true, line);
 49    return p;
 50}

 51
 52 void  mydelete( void *  p)
 53 ExpandedBlockStart.gifContractedBlock.gif {
 54    ContainerType::iterator it = myMap.find(p);
 55    assert(it!=myMap.end());
 56    myMap.erase(it);
 57    free(p);
 58}

 59
 60 class  AutoPtr
 61 ExpandedBlockStart.gifContractedBlock.gif {
 62public:
 63    explicit AutoPtr(int *p=0)
 64    :p_(p), refCnt_(mynew(int(1))), valid_(mynew(bool(p?true:false)))
 65ExpandedSubBlockStart.gifContractedSubBlock.gif    {}
 66
 67    ~AutoPtr()
 68ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 69        if(p_)
 70ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 71            mydelete (p_);
 72        }

 73
 74        (*refCnt_)--;
 75        
 76        *valid_ = false;
 77
 78        assert(*refCnt_>=0);
 79        if(*refCnt_==0)
 80ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 81            mydelete(refCnt_);
 82            mydelete(valid_);
 83        }

 84    }

 85
 86    bool empty() const
 87ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 88        if(!*valid_) 
 89            assert(p_==0);
 90        else
 91            assert(p_!=0);
 92
 93        return !(*valid_);
 94    }

 95private:
 96    friend class WeakPtr;
 97    AutoPtr(const AutoPtr&);
 98    AutoPtr& operator =(const AutoPtr&);
 99
100    int *p_;
101    bool *valid_;
102    int *refCnt_;    //weak ref cnt, always valid if one weakPtr or AutoPtr exist
103}
;
104
105 class  WeakPtr
106 ExpandedBlockStart.gifContractedBlock.gif {
107public:
108    // ctor
109    WeakPtr()
110    :p_(0), refCnt_(mynew(int(1))), valid_(mynew(bool(false)))
111ExpandedSubBlockStart.gifContractedSubBlock.gif    {
112    }

113
114    explicit WeakPtr(AutoPtr& p)    //p must be valid
115    :p_(&p), refCnt_(p.refCnt_),valid_(p.valid_)
116ExpandedSubBlockStart.gifContractedSubBlock.gif    {
117        (*p_->refCnt_)++;
118    }

119    
120    WeakPtr(const WeakPtr& rhs)    //p must be valid
121ExpandedSubBlockStart.gifContractedSubBlock.gif    {
122        construct(rhs);
123    }

124
125    ~WeakPtr()
126ExpandedSubBlockStart.gifContractedSubBlock.gif    {
127        destroy();
128    }

129
130    // get
131    bool empty() const
132ExpandedSubBlockStart.gifContractedSubBlock.gif    {
133        assert((*refCnt_)>=0);
134        return !(*valid_);
135    }

136
137    // operator    
138    WeakPtr& operator=(const WeakPtr &rhs)
139ExpandedSubBlockStart.gifContractedSubBlock.gif    {
140        if(this!=&rhs)
141ExpandedSubBlockStart.gifContractedSubBlock.gif        {
142            destroy();
143            construct(rhs);
144        }

145        return *this;
146    }

147
148private:
149    void destroy()
150ExpandedSubBlockStart.gifContractedSubBlock.gif    {
151        (*refCnt_)--;
152
153        assert((*refCnt_)>=0);
154        if(0==*refCnt_)
155ExpandedSubBlockStart.gifContractedSubBlock.gif        {
156            mydelete(refCnt_);
157            mydelete(valid_);
158        }

159    
160    }

161    void construct(const WeakPtr &rhs)
162ExpandedSubBlockStart.gifContractedSubBlock.gif    {
163        p_ = rhs.p_;
164        refCnt_ = rhs.refCnt_;
165        valid_ = rhs.valid_;
166        (*refCnt_)++;
167    }

168
169    AutoPtr *p_;
170    bool *valid_;
171    int *refCnt_;    //weak ref cnt, always valid if one weakPtr or AutoPtr exist
172}
;
173
174 void  Test()
175 ExpandedBlockStart.gifContractedBlock.gif {
176    WeakPtr p1;
177
178    assert(p1.empty());
179ExpandedSubBlockStart.gifContractedSubBlock.gif    {
180        AutoPtr p(mynew(int(100)));
181        p1 = WeakPtr(p);
182        assert(!p1.empty());
183        assert(!p.empty());
184    }

185    assert(p1.empty());
186
187    //mynew(int());
188}

189
190 void  main()
191 ExpandedBlockStart.gifContractedBlock.gif {
192    Test();
193    checkMemory();
194}

转载于:https://www.cnblogs.com/cutepig/archive/2009/11/25/1610915.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值