process(sp)与process(std::shared_ptr<int>(sp))的区别及引用计数疑问
代码示例
void process(std::shared_ptr<int> ptr) { std::cout << "inside the process function:" << ptr.use_count() << "\n"; } int main() { auto sp = std::make_shared<int>(); process(sp); process(std::shared_ptr<int>(sp)); return 0; }
问题
上述代码中两次调用process函数的输出均为2,这是为什么?
我原本认为第二次输出应该是3。std::shared_ptr<int>(sp)不是sp的副本吗?process函数的形参std::shared_ptr<int> ptr不又是一次拷贝吗?
解答
核心原因是临时shared_ptr对象作为函数参数时,会触发移动构造而非拷贝构造,避免了多余的引用计数增长:
第一次调用
process(sp):sp是左值,传递给形参ptr时执行拷贝构造,引用计数从1(main中的sp)增加到2,所以函数内输出2。函数结束后ptr销毁,引用计数回落至1。第二次调用
process(std::shared_ptr<int>(sp)):std::shared_ptr<int>(sp)是临时右值对象,创建它时拷贝sp,引用计数变为2;- 把这个临时对象传递给形参
ptr时,编译器会选择移动构造而非拷贝构造——移动构造只是转移临时对象的所有权,不会增加引用计数,同时临时对象会被立即销毁,引用计数维持在2; - 进入
process函数时,ptr的引用计数自然还是2。
你之前误以为会两次拷贝,是忽略了C++对临时右值参数的优化逻辑:移动语义避免了不必要的引用计数操作,既提升效率,也让最终的引用计数结果和第一次调用一致。
内容的提问来源于stack exchange,提问作者Zacon7
相关产品推荐
相关产品推荐

