智能指针

来源:互联网 发布:影像编辑软件 编辑:程序博客网 时间:2024/05/16 07:32

C++中的动态内存需要用户自己来维护,动态开辟的空间,在出函数作用域或者程序正常 退出前必须释放掉,否则会造成内存泄露,有时我们已经非常谨慎了,然防不胜 防:
智能指针特性:
1.构造和析构->RAII
(初始化)(释放资源)
//自动析构函数释放管理对象
2.operator*和operator->
//让我们能像原生一样使用智能指针访问管理对象
3.
a.AutoPtr->管理权转移 严重缺陷,尽量不要使用它 C++98/03
b.ScopedPtr->防拷贝 简单粗暴的方式
c.SharedPtr ->基于引用计数 功能强大,复杂,循环引用
d.WeakPtr->弱指针
防拷贝
1.只声明不定义
2.声明成私有或保护


RAII是一种解决问题的思想,智能指针是它的一种运用
1.构造函数初始化,析构函数释放资源;
2.像指针一样引用–operator*/operator->/operator[]
3.赋值–各种类型智能指针

RAII!=智能指针是RAII的一种应用,智能管理对象的释放问题,能够像指针一样使用;
RAII是一种规范,一种解决问题的思想,利用构造函数初始化,析构函数释放资源。

//#include <iostream>//#include <string>//using namespace std;////class Exception//{//public://  Exception(int id = 0, const char* msg = "")//      :_errId(id)//      ,_errMsg(msg)//  {}////  virtual const char* What() = 0 ;////  int GetErrId()//  {//      return _errId;//  }//protected://  int _errId;//  string _errMsg;//};////class OutOfRange : public Exception//{//public://  OutOfRange(const char* msg = "")//      :Exception(1, msg)//  {}//  //  virtual const char* What()//  {//      _errMsg += "越界";//      return _errMsg.c_str();//  }////};////class BadAlloc : public Exception//{//public://  BadAlloc(const char* msg = "")//      :Exception(2, msg)//  {}////  virtual const char* What()//  {//      _errMsg += "申请内存失败";//      return _errMsg.c_str();//  }//};////class OverFlow : public Exception//{};////template<class T, size_t N = 100>//class Array//{//public://  T& operator[](size_t index)//  {//      if (index >= N)//      {//          throw OutOfRange(__FUNCTION__);//      }////      return _a[index];//  }//protected://  T _a[N];//};////// new[]//template<class T>//T* NewArray(size_t N)//{//  T* p = (T*)malloc(sizeof(T)*N);//  if (p == 0)//  {//      //throw BadAlloc("模拟实现new[]的NewArray抛异常");//      throw BadAlloc(__FUNCTION__);//  }////  for (size_t i = 0; i < N; ++i)//  {//      new(p+i)T();//  }////  return p;//}////#include <vector>////int main()//{//  //try//  //{//  //  // vector//  //  Array<int, 10> a1;//  //  a1[0] = 0;//  //  a1[10] = 10;////  //  // new new[]//  //  string* p = NewArray<string>(10);//  //  char* p1 = NewArray<char>(0x7fffffff);//  //}//  //catch (Exception& e)//  //{//  //  cout<<e.What()<<endl;//  //}//  //try//  //{//  //  //char* p1 = new char[0x7fffffff];//  //  vector<int> v1;//  //  v1[1] = 0;//  //}//  //catch(exception& e)//  //{//  //  cout<<e.what()<<endl;//  //}////  return 0;//}//#include <iostream>//using namespace std;////// 智能指针//// RAII != 智能指针是RAII的一种应用,智能管理对象的释放问题,能够像指针一样使用//// RAII一种规范,一种解决问题的思想,利用构造函数初始化,析构函数释放资源////template<class T>//class AutoPtr//{//public://  AutoPtr(T* ptr = NULL)//      :_ptr(ptr)//  {}////  ~AutoPtr()//  {//      cout<<_ptr<<endl;//      delete _ptr;//  }////  T& operator*()//  {//      return *_ptr;//  }////protected://  T* _ptr;//};////void F1()//{//  int* p1 = new int;//  AutoPtr<int> ap1(p1);//  *p1 = 10;//  cout<<*p1<<endl;////  *ap1 = 20;//  cout<<*ap1<<endl;////  char* p2 = new char[0x7fffffff];//  AutoPtr<char> ap2(p2);//}////int main()//{//  try//  {//      F1();//  }//  catch(exception& e)//  {//      cout<<e.what()<<endl;//  }////  return 0;//}//////void F1()////{////    string* p1 = new string[10];////    char* p2 = NULL;////    try////    {////        p2 = new char[0x7fffffff];////        delete[] p1;////        throw; //异常的重新抛出////    }////////    // ...////////    delete[] p1;////    delete[] p2;////}#include <iostream>using namespace std;// 智能指针// RAII != 智能指针是RAII的一种应用,智能管理对象的释放问题,能够像指针一样使用// RAII一种规范,一种解决问题的思想,利用构造函数初始化,析构函数释放资源template<class T>class AutoPtr // auto_ptr std{public:    // RAII    AutoPtr(T* ptr = NULL)        :_ptr(ptr)    {}    // ap2(ap1)    AutoPtr(AutoPtr<T>& ap)        :_ptr(ap._ptr)    {        ap._ptr = NULL;    }    // ap2 = ap3;    AutoPtr<T>& operator=(AutoPtr<T>& ap)    {        if (this != &ap)        {            // 释放之前管理的对象            delete this->_ptr;            _ptr = ap._ptr;            // 转移管理权            ap._ptr = NULL;        }        return *this;    }    ~AutoPtr()    {        if(_ptr)        {            cout<<_ptr<<endl;            delete _ptr;            _ptr = NULL;        }    }    // 像指针一样使用    T& operator*()    {        return *_ptr;    }    T* operator->()    {        return _ptr;    }protected:    T* _ptr;};template<class T>class ScopedPtr{public:    // RAII    ScopedPtr(T* ptr = NULL)        :_ptr(ptr)    {}    ~ScopedPtr()    {        if (_ptr)        {            delete _ptr;        }    }    T& operator*()    {        return *_ptr;    }    T* operator->()    {        return _ptr;    }    // 1.只声明不定义    // 2.声明成私有private:    ScopedPtr(const ScopedPtr<T>& sp);    ScopedPtr<T>& operator=(const ScopedPtr<T>&);protected:    T* _ptr;};//template<class T>//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)//  :_ptr(sp._ptr)//{}//int main()//{//  AutoPtr<int> ap1(new int(10));//  AutoPtr<int> ap2 = ap1; // ap2(ap1);////  AutoPtr<int> ap3(new int(20));//  ap2 = ap3;////  ScopedPtr<int> sp4(new int(30));////    ScopedPtr<int> sp5(sp4);////  return 0;//}template<class T>struct Delete{    void operator()(T* ptr)    {        delete ptr;    }};template<class T>struct DeleteArray{    void operator()(T* ptr)    {        delete[] ptr;    }};template<class T, class D = Delete<T>>class SharedPtr{public:    SharedPtr(T* ptr)        :_ptr(ptr)        ,_countRef(new int(1))    {}    SharedPtr(const SharedPtr<T, D>& sp)        :_ptr(sp._ptr)        ,_countRef(sp._countRef)    {           ++(*_countRef);    }    // sp1 = sp4    SharedPtr<T, D>& operator=(const SharedPtr<T, D>& sp)    {        //         //this->Release();        if(_ptr != sp._ptr)        {            Release();            _ptr = sp._ptr;            _countRef = sp._countRef;            ++(*_countRef);        }        return *this;    }    inline void Release()    {        if (--(*_countRef) == 0)        {            cout<<_ptr<<endl;            //delete _ptr;            _del(_ptr);            delete _countRef;        }    }    ~SharedPtr()    {        Release();    }    //operator*()    //operator->()    int UseCount()    {        return *_countRef;    }protected:    T* _ptr;        //     int* _countRef; // 引用计数    D _del; // 定制的仿函数删除器};// 循环引用// 定制删除器int main(){    //SharedPtr<int> sp1(new int(10));    //SharedPtr<int> sp2(sp1);    //SharedPtr<int> sp3(sp2);    //SharedPtr<int> sp4(new int(20));    //sp1 = sp1;    //sp1 = sp2;    //sp1 = sp4;    //sp2 = sp4;    //sp3 = sp4;    SharedPtr<string> sp1(new string);    SharedPtr<string, DeleteArray<string>> sp2(new string[10]);    return 0;}//struct AA//{//  int _a1;//  int _a2;//};//int main()//{//  AutoPtr<int> ap1(new int(10));//  *ap1 = 20;////  // ap2像原生指针一样使用//  AutoPtr<AA> ap2(new AA);//  (*ap2)._a1 = 10;//  (*ap2)._a2 = 20;////  ap2->_a1 = 30;//  ap2.operator->()->_a1 = 50;////  ap2->_a2 = 40;////  AA* p2 = new AA;//  (*p2)._a1 = 10;//  (*p2)._a2 = 20;//  p2->_a1 = 30;//  p2->_a2 = 40;////  return 0;//}//#include <memory>//#include <boost/scoped_ptr.hpp>//#include <boost/shared_ptr.hpp>////int main()//{//  auto_ptr<int> ap1(new int(10));//  *ap1 = 20;//  auto_ptr<int> ap2(ap1);//  //*ap1 = 30;////  boost::scoped_ptr<int> sp3(new int(20));//  //boost::scoped_ptr<int> sp4(sp3);////  boost::shared_ptr<int> sp5(new int(30));//  boost::shared_ptr<int> sp6(sp5);//  cout<<sp5.use_count()<<endl;////  return 0;//}
0 0