为何交换两个shared_ptr后,其先前拷贝对象的指向内容未改变?
这本质是对std::shared_ptr工作机制的理解偏差,核心点在于:shared_ptr是存储目标地址的智能容器,拷贝操作复制的是目标地址,而非让拷贝对象与原指针绑定。
我们一步步拆解示例代码的逻辑:
std::shared_ptr<int> foo (new int(10)); // foo存储指向int(10)的内存地址 std::shared_ptr<int> bar (new int(20)); // bar存储指向int(20)的内存地址 auto abc = foo; // 拷贝foo的内容:abc也存储指向int(10)的地址,此时int(10)的引用计数变为2 std::swap (foo, bar); // 交换foo和bar存储的地址:foo现在存int(20)的地址,bar存int(10)的地址 // 注意:abc存储的地址完全没被修改,仍指向int(10) std::cout << "foo: " << *foo << '\n'; // 解引用foo的新地址,得到20 std::cout << "bar: " << *bar << '\n'; // 解引用bar的新地址,得到10 std::cout << "abc: " << *abc << '\n'; // 解引用abc的原始地址,得到10
用通俗的类比理解:把每个shared_ptr看成一张写着房间号的纸条。
- foo手里的纸条写着“10号房”,bar手里的写着“20号房”
- 拷贝abc就是复制了foo的纸条,abc手里也有一张“10号房”的纸条
- 交换foo和bar的纸条,只是foo现在拿“20号房”、bar拿“10号房”,但abc手里的纸条还是原来复制的“10号房”,自然指向的房间内容不会变
总结关键规则:
shared_ptr的拷贝操作只会复制它当前指向的目标地址,同时增加目标对象的引用计数std::swap仅交换两个shared_ptr自身存储的地址值,不会影响其他任何指向同一目标的shared_ptr- 除非主动修改abc的指向(比如重新赋值或swap),否则它的指向永远是拷贝时的那个内存地址
内容的提问来源于stack exchange,提问作者Thinium
相关产品推荐
相关产品推荐

