【C++】智能指针 |
您所在的位置:网站首页 › 智能指针c++实现 › 【C++】智能指针 |
std::unique_ptr std::shared_ptr std::weak_ptr std::unique_ptr 一个unique_ptr独享它指向的对象。也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。 离开作用域自动释放资源 具有move-only性质,独享资源所有权 可以指向数组 可以自定义deleter std::unique_ptr的构造函数,接受两个参数: 一个数据指针(这个指针可以指向单一数据,也可以是一个数组指针) 一个析构函数(在unique_ptr脱离作用域时调用) make_unique make_unique仅能new出一个数据指针,而无法指定析构函数。所以需要自定义析构函数的时候,不能调用make_unique函数来产生std::unique_ptr。 移动unique_ptr对象 在函数中作为参数 下面的代码将编译出错: 正确使用unique_ptr的方式: 小结 当unique_ptr被销毁时, 其指向的原始指针也自动被销毁。 unique_ptr无法被拷贝, 没有拷贝构造和拷贝赋值函数。 unique_ptr的所有权可以通过move操作转移,由移动构造和移动赋值函数实现。 unique_ptr默认通过delete实现对象销毁。 也可以在构造时指定unique_ptr的销毁函数。 使用默认的销毁函数时, unique_ptr的大小和原始指针相同。使用自定义销毁器时, unique_ptr会将销毁器的类封装在unique_ptr中, 因此应尽量使用无状态的函数对象(没有捕获的lambda表达式或仿函数)作为销毁器, 此时unique_ptr的大小仍然和原始指针相同。 ![]() std::shared_ptr shared_ptr的大小是固定的2倍原始指针大小, 一个是指向原始指针, 一个指向控制块. 共享资源所有权,对资源引用计数(从shared_ptr拷贝构造和拷贝赋值时会使引用计数+1,移动构造和移动赋值引用计数不变.) 当引用计数为0时,自动释放资源 可以指向数组 可以自定义deleter 一个 shared_ptr 对象的内存开销要比裸指针和无自定义 deleter 的 unique_ptr 对象略大。 shared_ptr 对象需要保存两个指针: 指向共享资源的指针。 引用计数等共享资源的控制信息。(指向控制信息的指针) shared_ptr 的 的 deleter 是保存在控制信息中,所以,是否有自定义 deleter 不影响 shared_ptr 对象的大小。 make_shared一般情况下, 更推荐使用make_shared来构造shared_ptr。 优点: 若创建原始指针和从原始指针创建shared_ptr之间抛出异常, 可能会发生内存泄漏; make_shared将对象的内存和控制块内存同时分配, 并同时释放. 这样可以提高执行效率。 缺点: 无法使用大括号初始化; 无法自定义销毁器; 对象内存和控制块内存同时分配同时释放. 这会导致在shared_ptr的引用计数为0, 但weak_ptr引用计数不为0的情况下. 控制块内存无法释放, 会导致对象的那块内存一直无法释放, 造成内存浪费。 ![]() std::weak_ptr weak_ptr是一种不控制所指向对象生存期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是会被释放。 weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。 由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock,此函数检查weak_ptr指向的对象是否存在。如果存在,lock返回一个指向共享对象的shared_ptr,如果不存在,lock将返回一个空指针 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |