智能指针shared_ptr的应用场景

智能指针shared_ptr的应用场景

既然智能指针shared_ptr能够帮助我们对程序中的内存资源进行很好的管理,避免内存泄漏或者内存访问错误的发生,那么我们能不能在任何时候都使用它来管理程序中的内存资源呢?

不能。shared_ptr增加了额外的引用计数而牺牲了一定的性能。

C++ 智能指针底层是采用引用计数的方式实现的。简单的理解,智能指针在申请堆内存空间的同时,会为其配备一个整形值(初始值为 1),每当有新对象使用此堆内存时,该整形值 +1;反之,每当使用此堆内存的对象被释放时,该整形值减 1。当堆空间对应的整形值为 0 时,即表明不再有对象使用它,该堆空间就会被释放掉。

总结起来,当出现以下情况时应该优先考虑使用shared_ptr来管理内存资源:

  1. 有多个使用者共同使用同一个对象,而这个对象没有一个明确的拥有者;
    这就好比教室里的电灯,大家都在使用这个电灯,但没有那个人来专门负责这个电灯的开关。往往是教室里一个人都没有,电灯却明晃晃地亮着。在这种场景下,我们就可以使用shared_ptr来管理这个电灯,通过shared_ptr,谁都可以使用这个电灯,但谁最后使用电灯谁就负责最后关灯。

  2. 某一个对象的复制操作很费时;
    如果一个对象的复制操作很费时,同时我们又需要在函数间传递这个对象,我们往往会选择传递指向这个对象的指针来代替传递对象本身,以此来避免对象的复制操作。既然选择使用指针,那么使用shared_ptr是一个更好的选择,即起到了向函数传递对象的作用,又不用为释放对象操心。

  3. 要把指针存入标准库容器;
    不管容器中保存的是普通指针还是智能指针,在使用上,两者并无太大区别,使用智能指针的优越性主要体现在容器使用完毕后清空容器的操作上。如果容器中保存的是普通指针,当我们在清空某个容器时,先要释放容器中指针所指向的资源,然后才能清空这些指针本身。例如,在SalarySys类的析构函数中,我们需要清空vecEmp容器中保存的Employee*指针:

class SalarySys
{
// …
public:
~SalarySys()
  {
      // …
      // 首先,释放容器中普通指针所指向的资源
     for(Employee* p : m_vecEmp)
      {
        delete p; // 释放指针所指向的对象
      }
      // 然后,用clear()函数清空容器
      m_vecEmp.clear();
  }
// …
private:
 vector<Employee*> m_vecEmp; // 保存普通指针的容器
}

如果把这个vecEmp容器中的普通指针替换成相应的shared_ptr,这个过程会简单的多。我们只需要使用clear()函数清空容器中保存的shared_ptr,而随着shared_ptr的释放,它会自动释放它所管理的资源,而无需我们主动去释放:

class SalarySys
{
// …
public:
~SalarySys()
  { 
      // …
      // 用clear()函数释放容器中的shared_ptr
      // shared_ptr在释放的时候也会连带地释放它所管理的Employee对象
      m_vecEmp.clear();
  }
// …
private:
 vector<shared_ptr<Employee>> m_vecEmp; // 保存shared_ptr的容器
}
 
  1. 当管理需要特殊清除方式的资源时,可以通过定制shared_ptr的删除器来实现。
    参考C++11 shared_ptr智能指针中关于定制shared_ptr定制删除器的介绍。

转载自你好,C++(79)什么时候应该使用智能指针呢?12.2.3 智能指针shared_ptr的应用场景

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值