你好,C++(79)什么时候应该使用智能指针呢?12.2.3 智能指针shared_ptr的应用场景
想要抢先看后面的章节?打赏本文10元,即可获得带插图全本下载地址!打赏完成记得私信我哦 :p
12.2.3 智能指针shared_ptr的应用场景
既然智能指针shared_ptr能够帮助我们对程序中的内存资源进行很好的管理,避免内存泄漏或者内存访问错误的发生,那么我们能不能在任何时候都使用它来管理程序中的内存资源呢?
不能。就像东坡肘子再好吃,我们也不可能天天吃。同样的道理,就算shared_ptr的作用再好再强大,我们也不可能处处使用。在这个世界上,任何的得到都是以某种牺牲为代价的。shared_ptr为了得到能够在内存资源的使用者个数为0时自动释放这块内存资源的能力,它增加了额外的引用计数而牺牲了一定的性能。如果在不需要shared_ptr的场景下过度滥用shared_ptr,不仅无助于内存资源的管理,反而可能会影响程序的性能,最终得不偿失。只有在合适的场景下使用shared_ptr,才能起到事半功倍的效果。
总结起来,当出现以下情况时应该优先考虑使用shared_ptr来管理内存资源:
有多个使用者共同使用同一个对象,而这个对象没有一个明确的拥有者;
这就好比教室里的电灯,大家都在使用这个电灯,但没有那个人来专门负责这个电灯的开关。往往是教室里一个人都没有,电灯却明晃晃地亮着。在这种场景下,我们就可以使用shared_ptr来管理这个电灯,通过shared_ptr,谁都可以使用这个电灯,但谁最后使用电灯谁就负责最后关灯。
某一个对象的复制操作很费时;
如果一个对象的复制操作很费时,同时我们又需要在函数间传递这个对象,我们往往会选择传递指向这个对象的指针来代替传递对象本身,以此来避免对象的复制操作。既然选择使用指针,那么使用shared_ptr是一个更好的选择,即起到了向函数传递对象的作用,又不用为释放对象操心。
要把指针存入标准库容器;
不管容器中保存的是普通指针还是智能指针,在使用上,两者并无太大区别,使用智能指针的优越性主要体现在容器使用完毕后清空容器的操作上。如果容器中保存的是普通指针,当我们在清空某个容器时,先要释放容器中指针所指向的资源,然后才能清空这些指针本身。例如,在SalarySys类的析构函数中,我们需要清空vecEmp容器中保存的Employee*指针:
class SalarySys
public:
~SalarySys()
// 首先,释放容器中普通指针所指向的资源
for(Employee* p : m_vecEmp)
delete p; // 释放指针所指向的对象
// 然后,用clear()函数清空容器
m_vecEmp.clear();
private:
vector<Employee*> vecEmp; // 保存普通指针的容器
}
如果把这个vecEmp容器中的普通指针替换成相应的shared_ptr,这个过程会简单的多。我们只需要使用clear()函数清空容器中保存的shared_ptr,而随着shared_ptr的释放,它会自动释放它所管理的资源,而无需我们主动去释放:
class SalarySys
public:
~SalarySys()
// 用clear()函数释放容器中的shared_ptr
// shared_ptr在释放的时候也会连带地释放它所管理的Employee对象
m_vecEmp.clear();