智能指针
来源:互联网 发布:影像编辑软件 编辑:程序博客网 时间: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