前言
本篇为C++最后一篇,我们来一起看看智能指针的内容,来明白智能指针的原理,以及用途.
💓 个人主页:小张同学zkf
⏩ 文章专栏:C++
若有问题 评论区见📝
🎉欢迎大家点赞👍收藏⭐文章
目录
1.智能指针的使用场景分析
下⾯程序中我们可以看到,new了以后,我们也delete了,但是因为抛异常导,后⾯的delete没有得到执⾏,所以就内存泄漏了,所以我们需要new以后捕获异常,捕获到异常后delete内存,再把异常抛出,但是因为new本⾝也可能抛异常,连续的两个new和下⾯的Divide都可能会抛异常,让我们处理起来很⿇烦。智能指针放到这样的场景⾥⾯就让问题简单多了。
double Divide ( int a, int b){// 当 b == 0 时抛出异常if (b == 0 ){throw "Divide by zero condition!" ;}else{return ( double )a / ( double )b;}}void Func (){// 这⾥可以看到如果发⽣除 0 错误抛出异常,另外下⾯的 array 和 array2 没有得到释放。// 所以这⾥捕获异常后并不处理异常,异常还是交给外⾯处理,这⾥捕获了再重新抛出去。// 但是如果 array2new 的时候抛异常呢,就还需要套⼀层捕获释放逻辑,这⾥更好解决⽅案// 是智能指针,否则代码太戳了int * array1 = new int [ 10 ];int * array2 = new int [ 10 ]; // 抛异常呢try{int len, time;cin >> len >> time;cout << Divide (len, time) << endl;}catch (...){cout << "delete []" << array1 << endl;cout << "delete []" << array2 << endl;delete [] array1;delete [] array2;throw ; // 异常重新抛出,捕获到什么抛出什么}// ...cout << "delete []" << array1 << endl;delete [] array1;cout << "delete []" << array2 << endl;delete [] array2;}int main (){try{Func ();}catch ( const char * errmsg){cout << errmsg << endl;}catch ( const exception& e){cout << e. what () << endl;}catch (...){cout << " 未知异常 " << endl;}return 0 ;}
2.RAII和智能指针的设计思路
RAII是Resource Acquisition Is Initialization的缩写,他是⼀种管理资源的类的设计思想,本质是
⼀种利⽤对象⽣命周期来管理获取到的动态资源,避免资源泄漏,这⾥的资源可以是内存、⽂件指
针、⽹络连接、互斥锁等等。RAII在获取资源时把资源委托给⼀个对象,接着控制对资源的访问,
资源在对象的⽣命周期内始终保持有效,最后在对象析构的时候释放资源,这样保障了资源的正常
释放,避免资源泄漏问题。
智能指针类除了满⾜RAII的设计思路,还要⽅便资源的访问,所以智能指针类还会想迭代器类⼀
样,重载
operator*/operator->/operator[]
等运算符,⽅便访问资源。
template < class T >class SmartPtr{public :// RAIISmartPtr (T* ptr):_ptr(ptr){}~ SmartPtr (){cout << "delete[] " << _ptr << endl;delete [] _ptr;}// 重载运算符,模拟指针的⾏为,⽅便访问资源T& operator *(){return *_ptr;}T* operator ->(){return _ptr;}T& operator []( size_t i){return _ptr[i];}private :T* _ptr;};double Divide ( int a, int b){// 当 b == 0 时抛出异常if (b == 0 ){throw "Divide by zero condition!" ;}else{return ( double )a / ( double )b;}}void Func (){// 这⾥使⽤ RAII 的智能指针类管理 new 出来的数组以后,程序简单多了SmartPtr< int > sp1 = new int [ 10 ];SmartPtr< int > sp2 = new int [ 10 ];for ( size_t i = 0 ; i < 10 ; i++){sp1[i] = sp2[i] = i;}int len, time;cin >> len >> time;cout << Divide (len, time) << endl;}int main (){try{Func ();}catch ( const char * errmsg){cout << errmsg << endl;}catch ( const exception& e){cout << e. what () << endl;}catch (...){cout << " 未知异常 " << endl;}return 0 ;}
3.C++标准库智能指针的使用
C++标准库中的智能指针都在<memory>这个头⽂件下⾯,我们包含<memory>就可以是使⽤了,