C++智能指针总结

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


#pragma once
//AutoPtr 智能指针
template < class T >
class AutoPtr
{
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;
};

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

void TestAutoPtr()
{
           int * p1 = new int (2);
           int * p2 = p1;
           int * p3;
          p3 = p2;

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

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

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



//ScopedPtr 智能指针
template < class T >
class ScopedPtr
{
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( const ScopedPtr < T >& sp);
           ScopedPtr < T > operator=( const ScopedPtr < T >& sp);

protected :
           T * _ptr;
};

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

void TestScopedPtr()
{
           ScopedPtr < int > sp1( new int (1));
           //ScopedPtr<int> sp2(sp1);
}


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

          ~SharedPtr()
          {
                   _Release();
          }
           //只是改变pcount
          SharedPtr( const SharedPtr < 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;
          }

           long GetCount()
          {
                    return *_pCount;
          }

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

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

void TestSharedPtr()
{
           SharedPtr < int > sp1( new int (1));
           SharedPtr < int > sp2(sp1);
          cout << sp1.GetCount() << endl;

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值