[c++]智能指针的实现

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 08:13   1167   0

智能指针最基本的概念是引用计数,也就是智能指针内部有一个计数器,记录了当前内存资源到底有多少指针在引用(可以访问这个资源),当新增加一个可以访问这个资源的引用时,计数器会加1,反之会减去1,当计数器为0时,智能指针会自动释放他所管理的资源。手动申请,自动释放,就是其智能的体现。

模拟auto_ptr

先看看库里的解释

auto_ptr

template<class T>
    class auto_ptr {
public:
    typedef T element_type;
    explicit auto_ptr(T *p = 0) throw();
    auto_ptr(const auto_ptr<T>& rhs) throw();
    auto_ptr<T>& operator=(auto_ptr<T>& rhs) throw();
    ~auto_ptr();
    T& operator*() const throw();
    T *operator->() const throw();
    T *get() const throw();
    T *release() const throw();
    };

The class describes an object that stores a pointer to an allocated object of type T. The stored pointer must either be null or designate an object allocated by a new expression. The object also stores an ownership indicator. An object constructed with a non-null pointer owns the pointer. It transfers ownership if its stored value is assigned to another object. The destructor for auto_ptr<T> deletes the allocated object if it owns it. Hence, an object of class auto_ptr<T> ensures that an allocated object is automatically deleted when control leaves a block, even via a thrown exception.

后面的英语看不懂,反正就是实现上面的声明函数;如下(以下代码均用类模版实现)

template<typename T>
class AutoPtr
{
public:
 AutoPtr()
  :_ptr(new int(1))
 {}
 ~AutoPtr()
 {
  delete _ptr;
  _ptr=NULL;
 }
 AutoPtr( AutoPtr<T>& ap)
 {
  _ptr=ap._ptr;
  ap._ptr=NULL;
 }
 AutoPtr<T>& operator=(AutoPtr<T>& ap)
 {
  delete _ptr;
  _ptr=ap._ptr;
  ap._ptr=NULL;
  return *this;
 }
 T* operator->()
 {
  return _ptr;
 }
 T& operator*()
 {
  return *_ptr;
 }
private:
 T* _ptr;
};
void AutoPtrTest()
{
 AutoPtr<int> ap1;
 *ap1=10;
 AutoPtr<int> ap2(ap1);
 AutoPtr<int> ap3=ap1;
  cout<<*ap1<<endl;
  cout<<*ap2<<endl;
  cout<<*ap3<<endl;
}
模拟实现scoped_ptr

scoped_ptr智能指针与std::auto_ptr不同,因为它是不传递所有权的。事实上它明确禁止任何想要这样做的企图!

template<typename T>
class ScopePtr
{
public:
 ScopePtr()
  :_ptr(new int(1))
 {}
 ~ScopePtr()
 {
  delete _ptr;
  _ptr=NULL;
 }
 T& operator *()
 {
  return *_ptr;
 }
 T* operator->()
 {
  return _ptr;
 }
protected:
 ScopePtr(const ScopePtr<T>& sp);
 ScopePtr<T>& operator=(const ScopePtr<T>& sp);
private:
 T* _ptr;
};
void ScopePtrTest()
{
 ScopePtr<int> sp1;
    *sp1=1;
 cout<<*sp1<<endl;
}


模拟实现Share_ptr

template <typename T>
class SharedPtr {
public:
 SharedPtr():
   p(NULL)
    , pCount(new int(1)) 
   { }
   explicit SharedPtr(T *pt)
    : p(pt)
    , pCount(new int(1)) 
   {    }
   SharedPtr(const SharedPtr &sp)
    : p(sp.p)
    , pCount(sp.pCount) 
   { 
    if (pCount) 
     ++*pCount;
   }
   SharedPtr& operator=(const SharedPtr&);
   ~SharedPtr();
   T& operator*() 
   { 
    return *p; 
   }
   const T& operator*() const 
   { 
    return *p;
   }
private:
 T *p;
 int *pCount;
};

template <typename T>
SharedPtr<T>::~SharedPtr()
{
 if (pCount && 0 == --*pCount)
 {
  delete p;   
  delete pCount;
 }
}
void SharedPtrTest()
{
 SharedPtr<int> sp1(new int(1));
 SharedPtr<int> sp2(sp1);
 SharedPtr<int> sp3=sp1;
 cout<<*sp1<<endl;
 cout<<*sp2<<endl;
 cout<<*sp3<<endl;
        cout<<sp1.pCount<<endl;
<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 24px;">        cout<<sp2.pCount<<endl;
        cout<<sp3.pCount<<endl;
}

这里有一个你在标准库中找不到的—引用数智能指针。大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章。最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引用计数的功能添加给类,或者是非插入,意思是说你不这样做。Boost
 shared_ptr是非插入类型的,这个实现使用一个从堆中分配来的引用计数器。关于提供参数化策略使得对任何情况都极为适合的讨论很多了,但是最终讨论的结果是决定反对聚焦于可用性。可是不要指望讨论的结果能够结束。
shared_ptr完成了你所希望的工作:他负责在不使用实例时删除由它指向的对象(pointee),并且它可以自由的共享它指向的对象



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP