目录
前言:
这是一篇又臭又长又精华的博客,需要每一个模块认真学习,仔细理解,这一部分也是C++面试常考的内容,那么废话不多说,just do it!
在这一篇章中我们需要重点学习:RAII思想、shared_ptr的实现和相关问题。
1.知识引入
1.1.异常安全问题
在C++学习进阶:异常-优快云博客我们引入这一段代码是为了提出异常的重新抛出这个作法,但是异常重新抛出一定就是解决异常安全问题的最优法吗?
#include<iostream>
#include<string.h>
using namespace std;
int Exception(int i)
{
int arr[5] = { 0, 1, 2, 3, 4 };
if (i >=5)
{
throw "数组越界";
}
else
{
return arr[i];
}
}
void Print()
{
int* array = new int[10];
try
{
int i = 0;
cin >> i;
cout << Exception(i) << endl;
// 不出现异常也是需要释放空间
delete[] array;
cout<<"释放array资源"<<endl;
}
catch(...)
{
delete[] array;
cout<<"释放array资源"<<endl;
}
}
int main()
{
try
{
Print();
}
catch (const char* errmsg)
{
cout << errmsg << endl;
}
catch (...)
{
cout << "未知异常" << endl;
}
}
我们看回这段代码,对于Print中,我们发现当不发生异常时我们也是需要继续的释放掉array这段空间,也就是在代码简洁上重新抛出显然是不太适合这个场景的。那么如何解决这个问题呢?先不着急,我们先引入一个新概念RAII。
1.2.RALL和智能指针雏形
RAII(Resource Acquisition Is Initialization)是C++编程中的一种技术,用于管理资源(如内存、文件句柄、网络连接等)的生命周期。RAII的核心思想是,将资源的获取(即初始化)与资源的释放(即析构)绑定到对象的生命周期上。通过这样做,可以确保资源在不再需要时得到正确的释放,从而避免资源泄漏和其他相关问题。
显然十分抽象,接下来我们结合上一段代码来体会一下RAII思想。
#include<iostream>
using namespace std;
// 智能指针的引入
template<class T>
class SmartPtr
{
public:
SmartPtr(T* ptr)
:_ptr(ptr)
{}
~SmartPtr()
{
delete _ptr;
cout << "~SmartPtr() 已经释放传入的指针资源" << endl;
}
private:
T* _ptr;
};
int Exception(int i)
{
int arr[5] = { 0, 1, 2, 3, 4 };
if (i >= 5)
{
throw "数组越界";
}
else
{
return arr[i];
}
}
void Print()
{
int* array = new int[10];
SmartPtr<int> s(array);
int i = 0;
cin >> i;
cout << Exception(i) << endl;
}
int main()
{
try
{
Print();
}
catch (const char* errmsg)
{
cout << errmsg << endl;
}
catch (...)
{
cout << "未知异常" << endl;
}
}
- 我们引入一个类,来实现传入指针的释放,这里我们传入了外部资源的指针,当我们在类内部释放这个指针,外部资源的指针同时也被释放(共用一块地址)。
- 而这个类SmartPtr就是智能指针,不过这是我们自己手搓的一个雏形,功能较少
- RAII思想:就是将具有资源的、且不方便管理资源的对象绑定到容易管理资源的另一个对象上,来实现资源的管理。而智能指针是这个思想的一种体现
另外我们通过黑窗口打印,也发现无论出现异常还是不出现异常,这个指针的资源最终都得到释放
通过上面的例子我们大概知道智能指针本质上就是实现一个对指针进行操作的对象,而在C++中封装为了在原生指针的基础上的一个具有多样功能的指针类,因而可以构造出“智能”指针对象……
2.智能指针的发展
智能指针是C++中用于自动管理内存生命周期的类模板。它们被设计为像原生指针一样使用,但提供了额外的功能来确保在适当的时候自动删除所指向的对象。智能指针通过封装原生指针并重载相关的操作符(如
*
和->
)来实现这一点,使得它们可以像使用普通指针一样方便。
智能指针主要有四种,分别是:auto_ptr
(C++98标准,已弃用)、unique_ptr
(C++11标准&#