ada*_*603 50 c++ smart-pointers shared-ptr weak-ptr unique-ptr
如果我理解正确,a weak_ptr
不会增加托管对象的引用计数,因此它不代表所有权.它只是让您访问一个对象,其生命周期由其他人管理.所以我真的不明白为什么一个weak_ptr
不能用a构建unique_ptr
,而只能用a 构建shared_ptr
.
有人能简单解释一下吗?
Dav*_*rtz 33
如果你考虑一下,weak_ptr
必须引用除了对象本身之外的东西.那是因为对象可以不再存在(当没有更强的指针时),weak_ptr
仍然必须引用包含对象不再存在的信息的东西.
有了a shared_ptr
,那就是包含引用计数的东西.但是使用a unique_ptr
,没有引用计数,因此没有包含引用计数的东西,因此当对象消失时没有任何东西可以继续存在.所以没有什么weak_ptr
可以参考.
也没有理智的方式来使用这样的weak_ptr
.要使用它,您必须有一些方法来保证在您使用它时不会破坏对象.这很容易shared_ptr
- 这就是它的shared_ptr
作用.但是你如何做到这一点unique_ptr
呢?你显然不能拥有其中的两个,并且其他东西必须已经拥有该对象,否则它将被破坏,因为你的指针很弱.
Dav*_*aim 16
std::weak_ptr
除非你将其转换为无法使用std::shared_ptr
的手段lock()
.如果标准允许你建议,那意味着你需要将std :: weak_ptr转换为唯一才能使用它,违反唯一性(或重新发明std::shared_ptr
)
为了说明,请看两段代码:
std::shared_ptr<int> shared = std::make_shared<int>(10);
std::weak_ptr<int> weak(shared);
{
*(weak.lock()) = 20; //OK, the temporary shared_ptr will be destroyed but the pointee-integer still has shared to keep it alive
}
Run Code Online (Sandbox Code Playgroud)
现在提出你的建议:
std::unique_ptr<int> unique = std::make_unique<int>(10);
std::weak_ptr<int> weak(unique);
{
*(weak.lock()) = 20; //not OK. the temporary unique_ptr will be destroyed but unique still points at it!
}
Run Code Online (Sandbox Code Playgroud)
有人说,你可能会建议只有一个unique_ptr
,你仍然可以解除引用weak_ptr
(不创建另一个unique_ptr
)然后没有问题.但那么unique_ptr
和shared_ptr
一个参考之间有什么区别?或者更多,unique_ptr
通过使用获得的常规和C指针有什么区别get
?
weak_ptr
它不是"一般非拥有资源",它有非常具体的工作 - 主要目标weak_ptr
是防止循环指向shared_ptr
哪些会导致内存泄漏.还有其他任何东西都需要用普通的unique_ptr
和shared_ptr
.
Mot*_*tti 12
A shared_ptr
基本上有两部分:
一旦引用计数降至零,就删除对象(#1).
现在weak_ptr
需要能够知道对象是否仍然存在.为了做到这一点,它必须能够看到引用计数对象(#2),如果它不为零,它可以shared_ptr
为对象创建一个(通过递增引用计数).如果计数为零,则返回空shared_ptr
.
现在考虑何时可以删除引用计数对象(#2)?我们必须等到没有shared_ptr
OR weak_ptr
对象引用它.为此目的,引用计数对象包含两个引用计数,一个强引用和一个弱引用.引用计数对象仅在其计数均为零时才会被删除.这意味着只有在所有弱引用消失后才能释放部分内存(这意味着隐藏的缺点make_shared
).
TL;博士; weak_ptr
取决于弱引用计数是其中的一部分shared_ptr
,不能weak_ptr
没有a shared_ptr
.
从概念上讲,没有什么能阻止一个实现,其中weak_ptr只提供访问权限,而unique_ptr控制生命周期.但是,有一些问题:
unique_ptr
不使用引用计数开头.添加用于管理弱引用的管理结构是可能的,但需要额外的动态分配.因为unique_ptr
应该避免对原始指针的任何(!)运行时开销,所以这种开销是不可接受的.weak_ptr
,你需要从中提取一个"真实"引用,它将首先验证指针是否先过期,然后给你这个真正的引用(shared_ptr
在本例中为a).这意味着您突然有一个对应该唯一拥有的对象的第二个引用,这是一个错误的配方.这不能通过返回一个混合的半强指针来解决,该指针只会暂时延迟对指针的可能破坏,因为你也可以存储那个,同时击败背后的想法unique_ptr
.只是想知道,你想用weak_ptr
这里解决什么问题?
小智 8
看起来每个人都在这里写关于 std::weak_ptr 但不是关于弱指针概念,我相信这是作者所要求的
我认为没有人提到为什么标准库不为 unique_ptr 提供weak_ptr。弱指针 CONCEPT 并不否认 unique_ptr 的使用。弱指针仅是对象已被删除的信息,因此它不是魔术,而是非常简单的广义观察者模式。
这是因为线程安全性和与shared_ptr的一致性。
您只是无法保证您的weak_ptr(从其他线程上存在的unique_ptr 创建的)在调用指向对象的方法期间不会被破坏。因为weak_ptr需要和std::shared_ptr保持一致,保证线程安全。您可以实现weak_ptr,它可以与unique_ptr一起正常工作,但只能在同一线程上 - 在这种情况下,锁定方法是不必要的。您可以检查 base::WeakPtr 和 base::WeakPtrFactory 的铬源 - 您可以通过 unique_ptr 自由使用它。Chromium 弱指针代码很可能基于最后一个成员销毁 - 您需要将工厂添加为最后一个成员,之后我相信 WeakPtr 会被告知对象删除(我不是 100% 确定) - 所以它看起来并不很难实施。
总的来说,使用带有弱指针概念的 unique_ptr 是可以的,恕我直言。
没有人提到问题的性能方面,所以让我扔掉0.02美元.
weak_ptr
必须以某种方式知道相应的shared_ptr
s 何时已经超出范围并且指向的对象已被解除分配和销毁.这意味着shared_ptr
需要以weak_ptr
某种方式将破坏传递给同一个对象.这有一定的成本 - 例如,需要更新全局哈希表,weak_ptr
从中获取地址(或者nullptr
如果对象被销毁).
这还涉及锁定多线程环境,因此对于某些任务来说可能太慢.
但是,目标unique_ptr
是提供零成本 RAII风格的抽象类.因此,它不应该招致比的任何其他成本delete
荷兰国际集团(或delete[]
荷兰国际集团)的动态分配的对象.例如,通过执行锁定或以其他方式保护的哈希表访问所施加的延迟可以与解除分配的成本相当,但是在这种情况下这是不希望的unique_ptr
.
归档时间: |
|
查看次数: |
18934 次 |
最近记录: |