c++_智能指针unique_ptr, 动态内存new与new[]与delete的 搭配性使用,new数组在QT对象树中的异常情况

智能指针的头文件

当我们去看 unique_ptrshared_ptr 的头文件时, 虽然他是在: <bits/unique_ptr.h> 这个文件

但是, 会有提示:

/** @file bits/shared_ptr.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{memory}
 */

当我们要使用他时, 应该: #include <memory>

shared_ptr的release操作

shared_ptr 是没有 release 操作的!!! 这意味着: shared_ptr 必须和 new操作 关联在一起, 否则就出错了!!

换句话说, 即: shared_ptr 不可以绑定: 非动态内存的对象!!

T data;  ' 全局对象 或 局部对象, 反正不是new出来的 '

shared_ptr< T> ptr( &data);

好了, 这个代码就彻底死了

ues_count == 1的那个ptr, 析构函数里, 一定会调用: data.~T()
data离开作用域, 也会调用 data.~T()

两次析构, 出错了

什么方式都救不了; 你使用ptr.reset(), 如果ptr.use_count() = 1, 还是会调用 析构!!!


解释下, 为什么shared_ptr 没有像unique_ptr一样, 有个release函数

之所以用shared_ptr, 即: 你有很多指针, 会指向同一个内存; 而这么多指针, 你很难管理;

如果这些指针, 你很好管理, 你都知道哪个是哪个, 那何必使用 (智能)指针呢? 所谓智能, 即你不知道该怎么管理

即此时很多指针, 你不知道该怎么管理 (所谓管理, 即不知道该什么时候 delete掉哪个指针)

假如支持release操作, T * p = ptr.release(), 这样做, 你可能有2个目的:

  • (1, 得到p 然后调用delete p) 如果不调用delete, 你使用get()也可以
    又有两种情况: (1, 此时ptr.use_count=1) (2, ptr.use_count > 1)
    如果是1: 你使用ptr.reset() 或 让ptr析构, 也可以达到相同目的
    如果是2: 你此时delete p;后, shared_ptr还是会析构, 造成两次析构
    故, 这个原因不成立

  • (2, 单纯的 想要解除ptr与内存的关系)
    又有两种情况: (1, 此时ptr.use_count=1) (2, ptr.use_count > 1)
    如果是1: 造成内存泄漏!!
    如果是2: 你使用ptr.reset()也可以呀~

故, 综上, 为shared_ptr 添加 release()函数, 并无作用

智能指针

裸指针
T * ptr = new T 我们日常在申请动态内存时, 通常是使用这种方式.

但是这种方式, 比较考验程序员的水平.
比如: T * p1, p2, p3; 这3个指针, 指向同一个内存.
当你要把这块内存 给delete掉: delete p1; p1 = nullptr;
但是, 此时p2 和 p3, 这两个指针; 他们并没用置空 但是, 他俩指向的内存 已经delete掉了.

除非, 你手动的 给p2 和 p3, 也给 delete掉 , 但这通常是很累人的.


所以, 引入 智能指针

  • ::std::auto_ptr , 他目前已经完全被 unique_ptr所取代.
  • ::std::unique_ptr
  • ::std::shared_ptr
  • ::std::weak_ptr

shared_ptr

顾名思义: 共享式的 指针. 允许多个指针, 同时指向 同一块内存.


构造函数

  • shared_ptr< Obj> ptr; 这个指针, 是指向nullptr的 , 即: 类似于 Obj * ptr = nullptr
  • shared_ptr< Obj> ptr( new Obj);
    (注意, shared_ptr类构造是 explicit的, 所以: ptr = new Obj;是不可行的
    (不推荐: Obj * p = new Obj; shared_ptr< Obj> ptr( p); 使用智能指针, 就应该 摒弃掉 以前的裸指针)

*取内容

shared_ptr< Obj> ptr( new Obj);

( *ptr).func();    ' *ptr取内容, 即一个Obj对象.   注意要带括号, 优先级 '

get函数 取指针

shared_ptr< Obj> ptr( new Obj);

( ptr.get())->func();   ' get函数, 获取该指针所指向的内存地址 (如果问空, 则返回nullptr) '

use_count函数

shared_ptr类, 有个use_count()函数, 表示: 该ptr所指向的内存, 被多少个shared_ptr指针所指向

{
   
	shared_ptr< Obj> ptr( new Obj);
	' ptr.use_count() == 1 '

	{
   
		auto a = ptr;
		' a/ptr .use_count() == 2 '
	}
	' ptr.use_count() == 1 '
}
' 出了这个作用域, ptr析构时, 他所指向的内存的 use_count变为0; '
' 会触发: Obj的析构!! '

shared_ptr< T> ptr

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值