如果我理解正确, weak_ptr
不会增加托管对象的引用计数,因此它不代表所有权。它只是让您访问一个对象,该对象的生命周期由其他人管理。所以我真的不明白为什么 weak_ptr
不能从 unique_ptr
构造,而只能是 shared_ptr
。
有人可以简要解释一下吗?
原文由 notadam 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果我理解正确, weak_ptr
不会增加托管对象的引用计数,因此它不代表所有权。它只是让您访问一个对象,该对象的生命周期由其他人管理。所以我真的不明白为什么 weak_ptr
不能从 unique_ptr
构造,而只能是 shared_ptr
。
有人可以简要解释一下吗?
原文由 notadam 发布,翻译遵循 CC BY-SA 4.0 许可协议
我通过在单个对象上实现 weak_ptr
的 MWE 向自己展示了这个问题。 (我在 X
上实现它,但是 X
可以是任何可以告诉我们它何时死亡的东西,例如 unique_ptr
带有自定义删除器)。
然而最终的问题是,在某些时候我们需要对弱指针本身进行引用计数,因为虽然 X
不是共享的,但弱指针 是共享 的。这让我们又回到了使用 shared_ptr
的循环。
也许这样做的唯一好处是单一 所有权 的 意图 更明确并且不能被违反,但是, 正如 Stroustrup 所建议并引用了这个答案,这可以通过 using
声明来暗示。
#include <iostream>
#include <memory>
template<typename T>
struct ControlBlock
{
T* Target;
explicit ControlBlock(T* target) : Target(target) {}
};
template<typename T>
struct WeakReference
{
std::shared_ptr<ControlBlock<T>> ControlBlock;
T* Get() { return ControlBlock ? ControlBlock->Target : nullptr; }
};
template<typename T>
struct WeakReferenceRoot
{
WeakReference<T> _weakRef;
WeakReferenceRoot(T* target) : _weakRef{std::make_shared<ControlBlock<T>>(target)} { }
const WeakReference<T>& GetReference() { return _weakRef; }
~WeakReferenceRoot() { _weakRef.ControlBlock->Target = nullptr; }
};
struct Customer
{
WeakReferenceRoot<Customer> Weak{this};
};
int main() {
WeakReference<Customer> someRef;
std::cout << "BEFORE SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
{
Customer obj{};
someRef = obj.Weak.GetReference();
std::cout << "IN SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
}
std::cout << "OUT OF SCOPE - WEAK REFERENCE IS " << someRef.Get() << "\n";
return 0;
}
原文由 c z 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
std::weak_ptr
不能使用,除非您通过std::shared_ptr
将其转换为lock()
。如果标准允许您的建议,则意味着您需要将 std::weak_ptr 转换为 unique 才能使用它,这违反了唯一性(或重新发明std::shared_ptr
)为了说明,看两段代码:
现在有了你的建议:
话虽如此,您可能会建议只有一个
unique_ptr
,您仍然可以取消引用weak_ptr
(无需创建另一个unique_ptr
则没有问题) .但是unique_ptr
和shared_ptr
之间有什么区别?或者,常规的unique_ptr
和使用get
获取的 C 指针有什么区别?weak_ptr
不适用于“一般非拥有资源”,它有一个非常具体的工作 -weak_ptr
shared_ptr
循环指向内存泄漏。其他任何事情都需要用普通的unique_ptr
和shared_ptr
来完成。