智能指针

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值