C++使用智能指针的必要性

评判智能指针的标准

在C/C++中,指针很重要,却是麻烦的来源。如果一个指针建立是没有初始化,那就是野指针(Vaild Pointer);如果一个指针指向已经释放的内存,那就是空悬指针(Dangling Pointer)。

一些比 C/C++ 更高级的语言都要极力避开指针,比如 Java 使用了垃圾回收,让系统自动回收用户申请的资源。

C++ 的智能指针,始于 Boost 准标准库,在 C++11 正式加入到C++标准模板库(STL)中。

智能指针的核心思想是:“ 程序员负责申请资源,释放留给智能指针 ”。所以我们可以最直观的感受到智能指针的好处是:“ 申请资源一劳永逸,老板再也不用担心内存泄露 ”。

但如果我们对智能指针的理解仅限于此,我们就会受到很多反对的声音的干扰。

  • “ 当年的 auto_ptr 多么垃圾 ”
  • 智能会带来许多额外的开销,C/C++的效率高的优势荡然无存
  • 智能指针的风格和原来的 new 格格不入
  • 遇到某些复杂的数据结构,或者所有权不明确的场景,还是得裸指针来

但是,如果仅仅将智能理解为防止内存泄露,是十分片面的。在考虑是否使用智能指针的时候,我们应该看到,该项技术到底是弊大于利还是利大于弊?

多线程的情况

如果我们考虑到多线程的情况,那么智能指针的优势几乎是压倒性的。

如今有一个多线程的程序,多个线程共同持有一个对象。那么:
(1) 如何确保在对象析构的时候,没有其他线程正在使用对象资源呢?
(2) 如果确保在对象析构后,没有其他线程会后续使用对象资源呢?

对于第一个问题,我们可以在对象外部建立一套锁机制,在对象析构和引用对象的时候通过锁来确保排他性访问。
对于第二个问题,我们也可以在对象外部奖励一套信号量机制,每当有线程应用对象,便对信号量进行P操作来计数,使用完毕时进行V操作。

但是,如果对于每个共享资源,我们新建一套保护机制,那么对于程序员来说是非常大的负担,同时也容易出错。

智能指针恰恰帮程序员解决了这一痛点,因为智能指针有本身就是通过一套原子性的计数机制实现的。


下面是一些 shared_ptr 的笔记。

shared_ptr 的申请对象

使用 shared_ptr 申请对象最好的方法是通过 make_shared<T>(args)函数返回 shared_ptr。其中 args 是对象的构造函数的参数。

shared_ptr<T> sp = make_shared<T>( args );

// 相当于 T *p = new T( args );
shared_ptr 的拷贝构造
  • 如果已经申请对象,可以用拷贝构造使多个 shared_ptr 指向同一个对象。
  • 当进行拷贝或赋值操作时,每个shared_ptr都会记录有多少个其他shared_ptr指向相同的对象。
  • 当我们给shared_ptr赋予一个新值或是shared_ptr被销毁时,计数器就会递减。
  • 当最后一个对象的最后一个shared_p
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值