shared_ptr<string> pNico(new string("Nico")); shared_ptr<string> pJutta(new string("Jutta")); // put them multiple times in a container vector<shared_ptr<string>> whoMadeCoffee; whoMadeCoffee.push_back(pJutta); whoMadeCoffee.push_back(pJutta); whoMadeCoffee.push_back(pNico); whoMadeCoffee.push_back(pJutta); whoMadeCoffee.push_back(pNico); pNico = nullptr; whoMadeCoffee.resize(2);
在程序的最后,当字符串的最后一个所有者被破坏时,共享指针将对其所引用的对象调用delete。这种删除不一定必须在范围的末尾进行。例如,将nullptr分配给
pNico
或调整向量的大小,使其仅包含前两个元素,将删除以nico
初始化的字符串的最后一个所有者。
(来自Josuttis,Nicolai M.。“ C ++标准库”。)
我的问题是,为什么在上述情况下不能保证在范围的末尾删除"Nico"
对象的内存?
尽管我们可以这样做
whoMadeCoffee.resize(2);
pNico = nullptr;
与"Nico"
关联的内存确实被删除。
有人可以解释一下区别吗?
答案 0 :(得分:4)
在程序结束时,字符串的最后一个所有者 销毁后,共享指针将为其引用的对象调用delete 至。这种删除不必不必要在最后完成 范围。
{{ (sender.firstName or sender.lastName ? "<strong>#{sender.firstName} #{sender.lastName}</strong>" : "<strong>Unknown</strong>")|raw }}
将在引用计数达到0时被销毁。在您的示例中,对于Nico,引用计数达到0(甚至在到达作用域末尾之前)。
如果您与当前范围之外的其他人共享,例如它具有返回string("Nico")
的函数,或者它是一个更简单的示例,则它可能超出其范围:
shared_ptr
在godbolt上直播