C++智能指针总结

智能指针RAII:资源分配及初始化,定义一个类来封装资源的分配和初始化,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放


#pragmaonce
//AutoPtr 智能指针
template<classT>
classAutoPtr
{
public:
          //构造函数
          AutoPtr(T*ptr)
                   :_ptr(ptr)
          {}
          //拷贝构造
          //把ap1股给ap2后,再把自己置为空,不再管理这个内存空间
          AutoPtr(AutoPtr<T>&ap)
                   :_ptr(ap._ptr)
          {
                   ap._ptr =NULL;
          }
          //赋值运算符重载
          //释放ap3,让ap3指向ap2所指空间,再把ap2置空
          AutoPtr<T>& operator=(AutoPtr<T>&ap)
          {
                   if(this!= &ap)
                   {
                             cout <<"delete:"<< _ptr << endl;
                             delete_ptr;

                             _ptr =ap._ptr;
                             ap._ptr =NULL;
                   }

                   return*this;
          }
          //析勾函数
          ~AutoPtr()
          {
                   if(_ptr)
                   {
                             cout <<"delete:"<< _ptr << endl;
                             delete_ptr;
                             _ptr =NULL;
                   }
          }
          //operator*
          T& operator*()
          {
                   return*_ptr;
          }
          //operator->
          T* operator->()
          {
                   return_ptr;
          }
          //getPtr
          T* GetPtr()
          {
                   return_ptr;
          }

protected:
          T* _ptr;
};

// 智能指针管理一块内存的释放
// 智能指针是一个类,有类似指针的功能
structNode
{
          int_data;
          Node* _next;
};

voidTestAutoPtr()
{
          int* p1 =newint(2);
          int* p2 = p1;
          int* p3;
          p3 = p2;

          *p1 = 10;
          //会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,
          //第二个就成为野指针
          AutoPtr<int> ap1(newint(1));
          AutoPtr<int> ap2 = ap1;       //AutoPtr ap2(ap1);
          //释放ap3,让ap3指向ap2所指空间,再把ap2置空
          AutoPtr<int> ap3(newint(3));
          ap3 = ap2;
          *ap3 = 10;
          //*ap1 = 30;

          AutoPtr<Node> apNode(newNode);
          apNode->_data = 10;

          deletep1;
}
//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,



//ScopedPtr 智能指针
template<classT>
classScopedPtr
{
public:
          //构造函数
          ScopedPtr(T*ptr)
                   :_ptr(ptr)
          {}
          //析勾函数
          ~ScopedPtr()
          {
                   if(_ptr)
                   {
                             cout <<"delete:"<< _ptr << endl;
                             delete_ptr;
                   }
          }
          //重载*
          T& operator*()
          {
                   return*_ptr;
          }
          //operator->
          T* operator->()
          {
                   return_ptr;
          }
          //GetPtr
          T* GetPtr()
          {
                   return_ptr;
          }
          
protected:
          //1.限定符为protected,不能进行拷贝,2.将拷贝构造和赋值运算符的重载声明出来
          //不能让他调用默认的,也不能在外面定义它
          ScopedPtr(constScopedPtr<T>& sp);
          ScopedPtr<T> operator=(constScopedPtr<T>& sp);

protected:
          T* _ptr;
};

//防止别人在类外面定义它
//template<class T>
//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)
//       :_ptr(sp._ptr)
//{}

voidTestScopedPtr()
{
          ScopedPtr<int> sp1(newint(1));
          //ScopedPtr<int> sp2(sp1);
}


//SharedPtr 利用引用计数来解决这个问题
template<classT>
classSharedPtr
{
public:
          SharedPtr(T*ptr)
                   :_ptr(ptr)
                   , _pCount(newlong(1))
          {}

          ~SharedPtr()
          {
                   _Release();
          }
          //只是改变pcount
          SharedPtr(constSharedPtr<T>&sp)
                   :_ptr(sp._ptr)
                   , _pCount(sp._pCount)
          {
                   ++(*_pCount);
          }

          ////赋值运算符的传统写法
          //SharedPtr<T>& operator=(const SharedPtr<T>& sp)
          //{
          //       if (this != &sp)
          //       {
          //                 this->_Release();                   
          //                 _pCount = sp._pCount;
          //                 _ptr = sp._ptr;
          //                 ++(*_pCount);
          //       }
          //       return *this;
          //}


          //现代写法
          SharedPtr<T>& operator=(SharedPtr<T>sp)
          {
                   swap(_ptr,sp._ptr);
                   swap(_pCount,sp._pCount);

                   return*this;
          }

          T& operator*()
          {
                   return*_ptr;
          }

          T* operator->()
          {
                   return_ptr;
          }

          T* GetPtr()
          {
                   return_ptr;
          }

          longGetCount()
          {
                   return*_pCount;
          }

protected:
          void_Release()
          {
                   //如果指向这个的引用计数为0才delete,其他时候只是前置减减
                   if(--(*_pCount) == 0)
                   {
                             delete_ptr;
                             delete_pCount;
                   }
          }

protected:
          T* _ptr;
          long* _pCount;
};

voidTestSharedPtr()
{
          SharedPtr<int> sp1(newint(1));
          SharedPtr<int> sp2(sp1);
          cout << sp1.GetCount() << endl;

          SharedPtr<int> sp3(newint(2));
          sp3 = sp1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值