智能指针实现了内存的自动化管理,使用它对一段内存空间进行管理,无需我们手动去释放这段内存空间,但智能指针的原理是什么?我们自己能否自实现一个智能指针用于内存的管理和监控?基于这些疑问,我们逐一进行介绍。
智能指针说白了就是C++标准库为我们封装好的一个对象,我们使用该对象对内存资源进行管理。智能指针对象在初始化时,便完成了对指定内存空间(或者对象资源)的创建,智能指针对象析构时可以释放它所管理的内存空间(或者对象资源),也就是RAII技术(资源获取即初始化)。现在举个简单的例子阐述智能指针的底层原理。
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
void Test()
{
cout<<"Test()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
}
class SmartPtr
{
public:
SmartPtr(A *a == nullptr)
{
cout<<"SmartPtr(A *a == nullptr)"<<endl;
_pa = a;
}
~SmartPtr()
{
cout<<"~SmartPtr()"<<endl;
delete _pa;
}
A & operator *()
{
return *_pa;
}
A *operator ->()
{
return _pa;
}
private:
A * _pa;
}
int main()
{
//SmartPtr类对象在初始化时便完成了对象A的构造,
//也即获取到了类A对象的内存资源,可以访问类A中的数据成员或者函数成员。
SmartPtr sp(new A);
//重载*和->运算符,使得对象sp拥有指针的特性
(*sp).Test();
sp->Test();
//当局部栈变量sp被析构时,便自动完成了A类对象内存资源的释放,
//也就是A类对象的内存资源由sp对象进行管理,“sp在,A在;sp亡,A亡”
return 0;
}
运行结果如下:
上面只是实现一个简单的智能指针,比如现在C++11中提出的shared_ptr、unique_ptr、weak_ptr等,那么这些智能指针又有什么样的性质?它们的底层原理又是怎样的?我们如何去自实现这些智能指针?我们将在下一节做详细地介绍。