You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何对std::shared_ptr执行std::move后use_count反而增加?

问题分析:std::move后std::shared_ptr引用计数异常的原因

你的问题核心在于缺少了<utility>头文件,导致std::move没有被正确识别,最终执行了复制构造而非移动构造,这才出现了引用计数不降反升的情况。

为什么会这样?

std::move是C++标准库中定义在<utility>头文件里的模板函数,它的作用是将左值转换为右值引用,从而触发移动语义。如果你的代码没有包含<utility>,编译器可能无法找到std::move的正确定义——在你使用的Apple LLVM 10.0.1这类旧版本编译器中,可能不会直接报错,而是将std::move(x)错误地处理为返回左值引用的恒等操作,相当于直接使用x本身。

这样一来,std::shared_ptr<Thing> y = std::move(x);这行代码就从移动构造变成了复制构造:

  • 复制构造会增加引用计数,所以x和y共享同一个对象,引用计数从1变成2。
  • 这完全违背了你原本期望的“移动后原指针置空、引用计数保持1”的结果。

解决方案

只需要在代码开头添加<utility>头文件即可:

#include <cstdio>
#include <memory>
#include <utility>  // 新增这一行
class Thing {
public:
    Thing(int N) : value(N) {}
    int value;
};
void print(const char* name, const std::shared_ptr<Thing>& sp) {  // 建议改成const引用
    printf("%s: { use_count=%i; }\n", name, (int)sp.use_count());
}
int main(int argc, char** argv) {
    std::shared_ptr<Thing> x(new Thing(4711));
    print("BEFORE x", x);
    std::shared_ptr<Thing> y = std::move(x);
    y->value = 4712;
    print(" AFTER x", x);
    print(" AFTER y", y);
    return 0;
}

重新编译运行后,你会得到符合预期的输出:

BEFORE x: { use_count=1; }
 AFTER x: { use_count=0; }
 AFTER y: { use_count=1; }

额外建议

你的print函数不需要修改传入的shared_ptr,所以最好将参数改为const std::shared_ptr<Thing>& sp——这不仅更符合代码语义,还能避免意外修改,同时也不会影响引用计数(因为const引用不会触发复制)。

内容的提问来源于stack exchange,提问作者Frank-Rene Schäfer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:49:29