模拟实现智能指针

来源:互联网 发布:秦美人浴池进阶数据 编辑:程序博客网 时间:2024/05/29 18:38

  首先说一下RAII(资源分配及初始化),定义一个类封装资源的分装和释放,在构造函数中完成资源的分配及初始化,析构函数完成资源的清理,是c++中常用的管理资源,避免内存泄漏。实现了自动释放资源。

  智能指针:自动管理指针指向的动态资源的释放。

  常见的有STL的auto_ptr,boost库的sharde_ptr,weak_ptr,scoped_ptr等等·····

  其区别是auto_ptr 使用了权限转移:

在拷贝构造中,浅拷贝时,释放空间会重复,所以深拷贝时将权限给新的指针。

AutoPtr(AutoPtr<T>& ap)
 {
   _ptr=ap._ptr;
   ap._ptr=NULL;
 }


  scoped_ptr可防止拷贝构造和赋值:

将拷贝构造和赋值写为私有和保护,不提供对象的访问权限。

  sharde_ptr使用了引用计数的方式,而与其搭配使用的weak_ptr解决了sharde_ptr的循环使用的问题

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

struct Node
{
   int _data;
   boost::shared_ptr<Node> _prev;
   boost::shared_ptr<Node> _next;

 ~Node()
 {       
  cout<<"~ListNode()" <<endl;
 }

};
void test()
{
   boost::shared_ptr <Node> p1( new Node ());
   boost::shared_ptr <Node> p2( new Node ());
   cout <<"p1->Count:" << p1. use_count()<<endl ;  
   cout <<"p2->Count:" << p2. use_count()<<endl ;
   p1->_next=p2;
   p2->_prev=p1;
   cout <<"p1->Count:" << p1. use_count ()<<endl ; 
   cout <<"p2->Count:" << p2. use_count ()<<endl ;
 

}
使指针指向陷入循环
                             A                                                                                                          B
  此时引用计数为2,但不调用析构函数。析构B时先析构A,析构A时要先析构B,引发循环,weak_ptr能使问题解决
#include<iostream>
#include<boost/shared_ptr.hpp>
#include<boost/weak_ptr.hpp>
using namespace std;
//using namespace boost;
//template<typename T>
struct Node
{
   int _data;
   /*boost::shared_ptr<Node> _prev;
   boost::shared_ptr<Node> _next;*/
   boost::weak_ptr<Node> _prev;
   boost::weak_ptr<Node> _next;
    ~Node()
 {       
  cout<<"~ListNode()" <<endl;
 }

};
void test()
{
   boost::shared_ptr <Node> p1( new Node ());
   boost::shared_ptr <Node> p2( new Node ());
   cout <<"p1->Count:" << p1. use_count()<<endl ;  
   cout <<"p2->Count:" << p2. use_count()<<endl ;
   p1->_next=p2;
   p2->_prev=p1;
   cout <<"p1->Count:" << p1. use_count ()<<endl ; 
   cout <<"p2->Count:" << p2. use_count ()<<endl ;
 

}
int main()
{
 test();
  system("pause");
  return 0;
}


  下面我简单的模拟实现了智能指针的部分功能,虽然没有库中的全面严谨,仅当小小的练习

shared_ptr:

#include<iostream>
using namespace std;
template<typename T>
class SharedePtr
{
public:
 SharedePtr(T* ptr)
  :_ptr(ptr),
  _pcount(new int(1))
 {
   cout<<_ptr<<endl;
 }
 ~SharedePtr()
 {
     Release();
 }
 SharedePtr<T>(SharedePtr<T>& sp)
 {
   _ptr=sp._ptr;
   _pcount=sp._pcount;
   _pcount++;
   return *this;
 
 }
 SharedePtr<T>& operator=(SharedePtr<T> ap)
 {
    std::swap(ap._ptr,_ptr);
    std::swap(ap._pcount,_pcount);
    return *this;
 }
     T& operator*()
   {
    return *_ptr;
   }

     T* operator->()
  {
   return _ptr;
  }
  T& ues_count()
  {
    return (*_pcount);
 
  }
private:
 void Release()
 {
  if(--*_pcount==0)
  {
   delete _ptr;
   delete _pcount;
  }
 }
 T* _ptr;
 int* _pcount;

};
int main()
{
  SharedePtr<int> ap1(new int(1));
  getchar();
  return 0;
}


auto_ptr:
#include<iostream>
using namespace std;
template<typename T>
class AutoPtr
{
public:
 AutoPtr(T* ptr)
  :_ptr(ptr)
 {
   cout<<_ptr<<endl;
 }
 ~AutoPtr()
 {
   delete _ptr;
 
 }
 AutoPtr(AutoPtr<T>& ap)
 {
   _ptr=ap._ptr;
   ap._ptr=NULL;
 }
 AutoPtr& 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;
};
int main()
{
  AutoPtr<int> ap1(new int(1));
  getchar();
  return 0;
}


scoped_ptr:
#include<iostream>
using namespace std;
template<typename T>
class Scoped_Ptr
{
public:
 Scoped_Ptr(T* ptr)
  :_ptr(ptr)
 {
   cout<<_ptr<<endl;
 }
 ~Scoped_Ptr()
 {
   if(_ptr!=NULL)
    delete _ptr;
 }
 T* operator->()
 {
   return _ptr;
 }
 T& operator[](int index)
 {
   return _ptr[index];
 
 }
 T* Get() 
  { 
   return _ptr; 
  } 
 
   void swap(Scoped_Ptr & b) 
   { 
       T *tmp = b._ptr;
    b._ptr = _ptr;  
    _ptr= tmp; 
    } 

private:
 T* _ptr;
 Scoped_Ptr(const Scoped_Ptr<T>& ap);
};
int main()
{
 
  Scoped_Ptr<int> sp1(new int(1)); 
  getchar();
  return 0;
}

1 0
原创粉丝点击