智能指针是如何实现的
主要技术是引用计数,以此来实现多个智能指针对象之间共享资源。
unique_ptr
这个智能指针是一个类模板,专门用于资源独享的情况。它的拷贝构造和赋值重载都被禁止了。
weak_ptr
这个智能指针不能单独用,一般是配合着shared_ptr,专门用于解决循环引用的问题。
shared_ptr
它的内部有两个指针,资源指针和控制块指针。
资源指针是指向动态分配的资源(如堆上的对象)的原始指针,也就是shared_ptr所管理的对象或者资源。当shared_ptr被释放的时候,这个指针也会调用其析构函数将其指向的资源释放掉。
控制块指针指向了一个控制块对象,也可以叫做引用计数块。这个部分主要存储shared_ptr的元数据。引用计数就是这里面的一个成员变量,里面还包括了deleter和一个指向共享资源的指针副本ptr(这个指针和shared_ptr对象中的资源指针一样)。
图来源:原PO
复制了一个shared_ptr后:
既然shared_ptr控制块有了指向共享资源的指针,为什么对象里也要有一个这样的指针?
概括:对象中的资源指针用于直接访问和操作资源,而控制块中的资源指针用于资源的引用计数、释放和管理。
智能指针是通过控制块里的资源指针访问共享资源的,所以缺少它将导致无法访问到共享资源。
而对于对象里的资源指针,一个比较大的作用是提高访问速率,可以通过对象提供的操作接口,不用每次都从控制块里去访问。其次就是有助于确保正确的资源销毁,因为两个资源指针的指向不一定是一样的,尽管大多数情况下是一样的,原因是对象里的资源指针是通过初始化过程中传入的指针决定的,后期还可能会被改变,例如自定义删除器和reset操作等。而控制块里的资源指针是通过智能指针内部管理的,通常不会被改编,指向原共享资源。所以它们的销毁操作自然也就不是一定同步的,那么就需要各自维护起来。