- 智能指针的必要性
为了避免由于资源操作不当导致的内存泄漏,采取通过对象生命周期实现对资源的管理。创建对象时托管资源,销毁资源实现资源的释放。其中,头文件中的智能指针类实现了上述功能。 - 智能指针分类及不同智能指针属性特征
auto_ptr<>
已经被废弃使用;
当执行auto对象复制操作时会,原auto对象会变为空指针,因此用户想要通过原auto指针操作对象时会发生段错误。
当两个auto使用同一个指针初始化后,进程结束后会执行多次的析构函数。
unique_ptr<>
表达的是对象语义,不能进行赋值或拷贝构造。 内部定义了移动语义构造函数,可以通过std::move 进行赋值
可以使用get()方法获取所托管资源的地址
shared_ptr<>
表达值语义,具有与unique_ptr<>相同的接口,并且可以使用复制和赋值函数
使用count()方法获取引用计数,进行复制时引用计数加。
不同的共享指针指向同一份资源,通过某一个指针操作资源发生的变换可以通过其他指针进行获取。
weak_ptr
shared_ptr由于循环引用可能导致的内存泄漏的隐患。
其中循环引用是指:
在堆空间中存放的shared_ptr对象相互托管,无法实现RAII技术通过栈对象生命周期管理资源的初衷。
解决方式是使用weak_ptr,使用weak_ptr托管资源时,通过shared_ptr复制或赋值不会改变use_count函数的数值。当栈对像生命周期结束时可以正确结束资源生命周期回收空间,但是资源收回顺序待定和weak_ptr具体托管哪个资源有关,并不会按照一般栈对象先进后出结束生命周期。
weak_ptr不能直接使用对象指针进行初始化。weak_ptr没有重载“->”和“ . ”函数,所以不能通过weak_ptr直接访问资源。可以使用lock成员函数,创建一个相应资源的shared_ptr之后进行资源的访问。并且可以通过expired函数获取所托管资源当前生命周期是否结束的信息。
- 智能指针间裸指针传递可能造成double free隐患
裸指针传递并不会改变shared_ptr的引用计数或unique_ptr。因此,当在智能指针对象间直接传递裸指针或通过reset成员函数传递时会产生double free的问题。
如果返回值是对象的裸指针,并且希望可以将该裸指针包装为智能指针的形式,可以继承enable_shared_from_this
- 智能指针需要自定义删除器
删除器为一个自定义的类,在类内部重载operator(),在该函数内执行资源回收操作。其中,operator(class *y)函数只能有一个类指针参数,且类类型与智能指针模板参数中资源类一致。