C++局部与全局shared_ptr是否需调用reset()?reset影响程序效率吗?
问题1:函数内的局部shared_ptr对象,以及文件级全局shared_ptr对象是否需要调用reset()?
问题2:reset()是否会影响C++程序的运行效率?
代码示例:初始化全局shared_ptr对象并传入函数
#include <iostream> #include <memory> std::shared_ptr<int> globalObj = std::make_shared<int>(5); int testFunc(std::shared_ptr<int> obj1) { std::shared_ptr<int> localObj = obj1; std::cout<<"localObj.count:" << localObj.use_count() << std::endl; std::cout << "localObj:" << *localObj <<std::endl; localObj.reset(); // 是否需要重置局部计数? std::cout<<"localObj.count:" << localObj.use_count() << std::endl; return 0; } int main() { std::cout<<"globalObj.count:" << globalObj.use_count() << std::endl; std::cout <<"globalObj:" << *globalObj <<std::endl; testFunc(globalObj); std::cout<<"globalObj.count:" << globalObj.use_count() << std::endl; std::cout <<"globalObj:" << *globalObj <<std::endl; globalObj.reset(); // 是否需要重置全局计数? std::cout<<"globalObj.count:" << globalObj.use_count() << std::endl; return 0; }
运行输出
globalObj.count:1 globalObj:5 localObj.count:3 localObj:5 localObj.count:3 globalObj.count:1 globalObj:5 globalObj.count:1
问题解答
问题1:是否需要调用reset()?
- 局部shared_ptr对象:完全没必要手动调用
reset()。局部shared_ptr(比如示例里的localObj)在函数执行完毕离开作用域时,会自动触发析构函数,把引用计数减1。看运行输出就能发现,调用localObj.reset()后引用计数还是3——这是因为reset()只是让localObj不再指向原对象,但函数参数obj1(是globalObj的拷贝)还持有引用,所以计数没降。要是不调用reset(),函数结束时localObj和obj1都会被销毁,引用计数会从3回落回1(也就是globalObj的初始计数)。手动reset()纯粹是多此一举,没任何实际作用。 - 文件级全局shared_ptr对象:分情况判断:
- 如果程序结束前还需要使用这个全局对象,不用调用
reset()。程序退出时,全局对象会被自动销毁,引用计数减1,一旦计数到0,就会自动释放管理的内存。 - 要是想在程序运行期间提前释放内存,或者让它指向新对象,那可以调用
reset()。不过示例里main末尾调用reset()后计数显示为1,这大概率是测试环境的小问题——理论上reset()后globalObj不再指向原对象,原对象的引用计数会降到0并被释放,空的shared_ptr的use_count()应该返回0。核心逻辑不变:不需要提前释放资源的话,完全没必要手动调用reset()。
- 如果程序结束前还需要使用这个全局对象,不用调用
问题2:reset()是否影响运行效率?
reset()的开销极小,核心操作就是两步:一是把当前shared_ptr的引用计数减1(计数到0就释放对象),二是让shared_ptr指向新对象(不带参数就指向空)。虽然引用计数的操作是原子性的(保证线程安全),原子操作比普通操作略慢,但这种差距在绝大多数场景下可以忽略不计。只有在极端高频调用的场景里,才需要考虑这点开销,普通业务代码完全不用纠结这个。
内容的提问来源于stack exchange,提问作者chandu
相关产品推荐
相关产品推荐

