您的位置:首页 > 编程语言 > C语言/C++

C++智能指针总结

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

[align=left]#pragmaonce[/align]
[align=left]//AutoPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classAutoPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left]          //构造函数[/align]
[align=left]          AutoPtr(T*ptr)[/align]
[align=left]                   :_ptr(ptr)[/align]
[align=left]          {}[/align]
[align=left]          //拷贝构造[/align]
[align=left]          //把ap1股给ap2后,再把自己置为空,不再管理这个内存空间[/align]
[align=left]          AutoPtr(AutoPtr<T>&ap)[/align]
[align=left]                   :_ptr(ap._ptr)[/align]
[align=left]          {[/align]
                   ap._ptr
=NULL;
[align=left]          }[/align]
[align=left]          //赋值运算符重载[/align]
[align=left]          //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
          AutoPtr<T>&
operator=(AutoPtr<T>&ap)
[align=left]          {[/align]
                   if(this!=
&ap)
[align=left]                   {[/align]
                             cout <<"delete:"<<
_ptr << endl;
[align=left]                             delete_ptr;[/align]
[align=left]
[/align]
[align=left]                             _ptr =ap._ptr;[/align]
                             ap._ptr
=NULL;
[align=left]                   }[/align]
[align=left]
[/align]
[align=left]                   return*this;[/align]
[align=left]          }[/align]
[align=left]          //析勾函数[/align]
[align=left]          ~AutoPtr()[/align]
[align=left]          {[/align]
[align=left]                   if(_ptr)[/align]
[align=left]                   {[/align]
                             cout <<"delete:"<<
_ptr << endl;
[align=left]                             delete_ptr;[/align]
[align=left]                             _ptr =NULL;[/align]
[align=left]                   }[/align]
[align=left]          }[/align]
[align=left]          //operator*[/align]
          T&
operator*()
[align=left]          {[/align]
[align=left]                   return*_ptr;[/align]
[align=left]          }[/align]
[align=left]          //operator->[/align]
          T*
operator->()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]          //getPtr[/align]
          T*
GetPtr()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
          T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]// 智能指针管理一块内存的释放[/align]
[align=left]// 智能指针是一个类,有类似指针的功能[/align]
[align=left]structNode[/align]
[align=left]{[/align]
[align=left]          int_data;[/align]
          Node*
_next;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestAutoPtr()[/align]
[align=left]{[/align]
          int*
p1 =newint(2);
          int*
p2 = p1;
          int*
p3;
[align=left]          p3 = p2;[/align]
[align=left]
[/align]
[align=left]          *p1 = 10;[/align]
[align=left]          //会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,[/align]
[align=left]          //第二个就成为野指针[/align]
          AutoPtr<int>
ap1(newint(1));
          AutoPtr<int>
ap2 = ap1;       //AutoPtr ap2(ap1);
[align=left]          //释放ap3,让ap3指向ap2所指空间,再把ap2置空[/align]
          AutoPtr<int>
ap3(newint(3));
[align=left]          ap3 = ap2;[/align]
[align=left]          *ap3 = 10;[/align]
[align=left]          //*ap1 = 30;[/align]
[align=left]
[/align]
          AutoPtr<Node>
apNode(newNode);
[align=left]          apNode->_data = 10;[/align]
[align=left]
[/align]
[align=left]          deletep1;[/align]
[align=left]}[/align]
[align=left]//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//ScopedPtr 智能指针[/align]
[align=left]template<classT>[/align]
[align=left]classScopedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left]          //构造函数[/align]
[align=left]          ScopedPtr(T*ptr)[/align]
[align=left]                   :_ptr(ptr)[/align]
[align=left]          {}[/align]
[align=left]          //析勾函数[/align]
[align=left]          ~ScopedPtr()[/align]
[align=left]          {[/align]
[align=left]                   if(_ptr)[/align]
[align=left]                   {[/align]
                             cout <<"delete:"<<
_ptr << endl;
[align=left]                             delete_ptr;[/align]
[align=left]                   }[/align]
[align=left]          }[/align]
[align=left]          //重载*[/align]
          T&
operator*()
[align=left]          {[/align]
[align=left]                   return*_ptr;[/align]
[align=left]          }[/align]
[align=left]          //operator->[/align]
          T*
operator->()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]          //GetPtr[/align]
          T*
GetPtr()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]          [/align]
[align=left]protected:[/align]
[align=left]          //1.限定符为protected,不能进行拷贝,2.将拷贝构造和赋值运算符的重载声明出来[/align]
[align=left]          //不能让他调用默认的,也不能在外面定义它[/align]
          ScopedPtr(constScopedPtr<T>&
sp);
          ScopedPtr<T>
operator=(constScopedPtr<T>&
sp);
[align=left]
[/align]
[align=left]protected:[/align]
          T*
_ptr;
[align=left]};[/align]
[align=left]
[/align]
[align=left]//防止别人在类外面定义它[/align]
[align=left]//template<class T>[/align]
[align=left]//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)[/align]
[align=left]//       :_ptr(sp._ptr)[/align]
[align=left]//{}[/align]
[align=left]
[/align]
[align=left]voidTestScopedPtr()[/align]
[align=left]{[/align]
          ScopedPtr<int>
sp1(newint(1));
[align=left]          //ScopedPtr<int> sp2(sp1);[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]//SharedPtr 利用引用计数来解决这个问题[/align]
[align=left]template<classT>[/align]
[align=left]classSharedPtr[/align]
[align=left]{[/align]
[align=left]public:[/align]
[align=left]          SharedPtr(T*ptr)[/align]
[align=left]                   :_ptr(ptr)[/align]
[align=left]                   , _pCount(newlong(1))[/align]
[align=left]          {}[/align]
[align=left]
[/align]
[align=left]          ~SharedPtr()[/align]
[align=left]          {[/align]
[align=left]                   _Release();[/align]
[align=left]          }[/align]
[align=left]          //只是改变pcount[/align]
[align=left]          SharedPtr(constSharedPtr<T>&sp)[/align]
[align=left]                   :_ptr(sp._ptr)[/align]
[align=left]                   , _pCount(sp._pCount)[/align]
[align=left]          {[/align]
[align=left]                   ++(*_pCount);[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]          ////赋值运算符的传统写法[/align]
          //SharedPtr<T>& operator=(const
SharedPtr<T>& sp)
[align=left]          //{[/align]
[align=left]          //       if (this != &sp)[/align]
[align=left]          //       {[/align]
[align=left]          //                 this->_Release();                   [/align]
          //                 _pCount
= sp._pCount;
          //                 _ptr =
sp._ptr;
[align=left]          //                 ++(*_pCount);[/align]
[align=left]          //       }[/align]
[align=left]          //       return *this;[/align]
[align=left]          //}[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]          //现代写法[/align]
          SharedPtr<T>&
operator=(SharedPtr<T>sp)
[align=left]          {[/align]
[align=left]                   swap(_ptr,sp._ptr);[/align]
[align=left]                   swap(_pCount,sp._pCount);[/align]
[align=left]
[/align]
[align=left]                   return*this;[/align]
[align=left]          }[/align]
[align=left]
[/align]
          T&
operator*()
[align=left]          {[/align]
[align=left]                   return*_ptr;[/align]
[align=left]          }[/align]
[align=left]
[/align]
          T*
operator->()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]
[/align]
          T*
GetPtr()
[align=left]          {[/align]
[align=left]                   return_ptr;[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]          longGetCount()[/align]
[align=left]          {[/align]
[align=left]                   return*_pCount;[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
[align=left]          void_Release()[/align]
[align=left]          {[/align]
[align=left]                   //如果指向这个的引用计数为0才delete,其他时候只是前置减减[/align]
                   if(--(*_pCount)
== 0)
[align=left]                   {[/align]
[align=left]                             delete_ptr;[/align]
[align=left]                             delete_pCount;[/align]
[align=left]                   }[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]protected:[/align]
          T*
_ptr;
          long*
_pCount;
[align=left]};[/align]
[align=left]
[/align]
[align=left]voidTestSharedPtr()[/align]
[align=left]{[/align]
          SharedPtr<int>
sp1(newint(1));
          SharedPtr<int>
sp2(sp1);
[align=left]          cout << sp1.GetCount() << endl;[/align]
[align=left]
[/align]
          SharedPtr<int>
sp3(newint(2));
[align=left]          sp3 = sp1;[/align]

[align=left]}[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: