3

我在使用时偶然发现了这种行为std::weak_ptrstd::make_shared我发现它有点奇怪。我正在使用 C++11。

#include <iostream>
#include <memory>

int main()
{
  std::weak_ptr<int> weak;

  std::shared_ptr<int> shared {std::make_shared<int>(42)};
  weak = shared;
  std::cout << "Meaning of life: " << *weak.lock() << std::endl;

  weak = std::make_shared<int>(23);
  std::cout << "Meaning of life: " << *weak.lock() << std::endl;

  return 0;
}

第一个std::cout打印正常,第二个给我一个段错误。我尝试查看cppreferencestd::weak_ptr的页面和std::shared_ptr页面,但我仍然不明白为什么会发生这种情况。必须创建一个临时对象对我来说很麻烦,这是在 C++14 中已经解决的问题还是我没有看到的东西?

谢谢!

4

2 回答 2

5

如果仍然存在指向同一底层对象的对象,weak_ptr则只能在锁定后取消引用。shared_ptr

在你的第一部分

std::shared_ptr<int> shared {std::make_shared<int>(42)};
weak = shared;
std::cout << "Meaning of life: " << *weak.lock() << std::endl;

确实如此。在第二部分

weak = std::make_shared<int>(23);
std::cout << "Meaning of life: " << *weak.lock() << std::endl;

事实并非如此,因为它shared_ptr是一个临时对象。

您在这里遇到的正是weak_ptr构建的目的 - 只要其他一些shared_ptr指向同一底层对象,它就有效。这就是它的目的

std::weak_ptr 是一个智能指针,它持有对由 std::shared_ptr 管理的对象的非拥有(“弱”)引用...如果此时原始 std::shared_ptr 被销毁,则该对象的生命周期被扩展直到临时 std::shared_ptr 也被破坏。

于 2017-05-31T11:01:46.847 回答
4

这是因为您在这一行中创建了一个临时共享指针并立即将其分配给一个弱指针:

weak = std::make_shared<int>(23);

赋值运算符结束后,临时共享指针被破坏,引用计数为0(因为弱指针不会增加引用计数器),因此堆上的资源被删除。

于 2017-05-31T11:01:53.600 回答