C++智能指针

文章目录

一、智能指针的目的和基本原理

一般new出来的对象会用普通指针引用,此时申请的堆上的资源需要我们手动使用delete进行资源释放。如果忘记delete或者delete之前程序出现未可预知的意外,之前申请的资源就不能正常释放,造成内存泄露;

智能指针是对裸指针(普通指针)的封装,智能指针利用了栈上对象在跳出作用域会自动析构的原理,让智能指针去管理资源。所以智能指针对象一般不能new。

二、不带引用计数的智能指针

2.1 auto_ptr

auto_ptr只能管理一个对象,如果使用拷贝构造函数进行auto_ptr初始化,

#include "iostream"
#include "string"

using namespace std;

int main() {
    auto_ptr<int> p1(new int(10));
    auto_ptr<int> p2(p1);
    *p1 = 20;
    return 0;
}

C++智能指针
auto_ptr已经过期,如上的这种问题导致C++并不建议使用auto_ptr。

2.2 scoped_ptr

基于以上auto_ptr的问题,scoped_ptr直接禁止使用拷贝构造函数和赋值重载运算符函数。scoped_ptr部分源码如下所示:

template<class T> class scoped_ptr
{
private:
    T * px;

    scoped_ptr(scoped_ptr const &);
    scoped_ptr & operator=(scoped_ptr const &);

    typedef scoped_ptr<T> this_type;

    void operator==( scoped_ptr const& ) const;
    void operator!=( scoped_ptr const& ) const;

2.3 unique_ptr

从名字就可以看出来unique_ptr只能管理一个资源。
而且unique_ptr也删除了拷贝构造函数和赋值运算符重载函数。
但是unique_ptr提供了一个带右值引用的拷贝构造函数和赋值运算符重载函数,使用方法如下所示:


unique_ptr<int> ptr(new int);

unique_ptr<int> ptr2 = std::move(ptr);
ptr2 = std::move(ptr);

三、带引用计数的智能指针

3.1 shared_ptr

如名字所示,多个智能指针对象指向同一个内存资源,智能指针对象里维护了一个引用计数器对象,表示当前指针指向的对象被多少个智能指针引用。当引用计数减到0的时候才真正的进行对象的析构。
shared_ptr维护的计数器对象是在new在堆上的,
shared_ptr又叫做强智能指针。

3.2 weak_ptr

C++智能指针
如上的情况叫做交叉引用,A对象和B对象的引用计数都是2,如果使用shared_ptr,如果ptrA或者ptrB不再引用对象,对象本应该被释放,但是实际上引用计数不为0,对象不能被释放,这种情况就要使用weak_ptr。

弱智能指针weak_ptr区别于shared_ptr之处在于:

1、weak_ptr不会改变资源的引用计数,只是一个观察者的角色,通过观察shared_ptr来判定资源是否存在
2、weak_ptr持有的引用计数,不是资源的引用计数,而是同一个资源的观察者的计数
3、weak_ptr没有提供常用的指针操作,无法直接访问资源,需要先通过lock方法提升为shared_ptr强智能指针,才能访问资源。

从shared_ptr和weak_ptr之间的区别可以看出,在对象内部引用其他对象的时候使用weak_ptr,外部的时候使用shared_ptr。

Original: https://blog.csdn.net/weixin_39861267/article/details/127824068
Author: 圆月弯刀鞘
Title: C++智能指针

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/660882/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球