简体   繁体   English

C ++智能指针中带循环的引用计数

[英]reference counting with cycles in C++ smart pointer

In shared_ptr smart pointer, reference counting is used. 在shared_ptr智能指针中,使用引用计数。 However, reference counting has a problem, that it can't break cycles of reference. 但是,引用计数有一个问题,它不能打破引用循环。

I have four questions with this issue. 关于这个问题,我有四个问题。

1) Could anybody offer me one snippet in which the cycles of reference happened? 1)有人可以给我一个片段,其中参考周期发生了吗?

2) If it can't break cycles of reference, how does RCSP guarantee success resource manage? 2)如果不能打破参考周期,RCSP如何保证成功资源管理? Is there any way to break the cycles with 3rd party product? 有没有办法打破第三方产品的周期?

3) Is there anyway to avoid the cycles of reference? 3)无论如何都要避免参考周期?

4) How about other smart pointers? 4)其他智能指针怎么样? How does they deal with the source manage? 他们如何处理源管理? For example, share_ptr, scope_ptr? 例如,share_ptr,scope_ptr?

Many thanks! 非常感谢!

The usual way to avoid cycles is to use weak references in any one point of the cycle. 避免循环的通常方法是在循环的任何一个点使用弱引用。 shared_ptr has a companion type, weak_ptr , which is designed for this purpose. shared_ptr有一个伴随类型weak_ptr ,它是为此目的而设计的。

Which part of the cycle to weaken is a matter of design. 削弱周期的哪一部分是设计问题。 In designs where "parent" objects own "children", then the reference from parent to child should be strong ( shared_ptr ), and the reference from child back to parent should be weak ( weak_ptr ). 在“父”对象拥有“子”的设计中,从父级到子级的引用应该是强的( shared_ptr ),并且从子级到父级的引用应该是弱的( weak_ptr )。

Practical uses that involve cycles are quite a few kinds of graphs. 涉及周期的实际用途是相当多的图形。 A trivial snippet (though one that's unlikely to happen in real life) would be something like: 一个微不足道的片段(虽然在现实生活中不太可能发生)将是这样的:

struct node {
    node *next;
};

int create_cycle() {
    node *a = new node;
    a.next = a;
}

After create_cycle returns, the node we just allocated contains a reference to itself, but there's no other point to it, so a reference counter won't collect it even though it's garbage. 在create_cycle返回之后,我们刚刚分配的节点包含对它自己的引用,但没有其它指向它,因此引用计数器即使它是垃圾也不会收集它。

Chris Jester-Young has already dealt with cycle breaking with smart pointers from a practical viewpoint. Chris Jester-Young已经从实用的角度处理了智能指针的循环中断。 He didn't go into any real detail about how it works internally though. 尽管如此,他并没有详细介绍它的内部工作原理。

A weak_ptr is sort of a doubly-indirect pointer. weak_ptr是一种双重间接指针。 Ie the weak_ptr doesn't give acces directly with an object. 即weak_ptr不直接提供对象的访问。 Instead, to get to the object, you have to convert the weak_ptr to a shared_ptr, then use that to get to the object -- but the attempt to convert the weak_ptr to a shared_ptr will only succeed if there's still at least one other shared_ptr to the managed object (so the object has a nonzero reference count and still exists). 相反,要访问该对象,您必须将weak_ptr转换为shared_ptr,然后使用它来获取该对象 - 但是,如果仍然至少有一个其他shared_ptr,那么将weak_ptr转换为shared_ptr的尝试将只会成功托管对象(因此该对象具有非零引用计数且仍然存在)。

As such, a weak_ptr gives you access to an object as long as it exists, but "knows" when the object ceases to exist and doesn't give you access to the (now freed) memory where the object used to be if the object has been destroyed. 因此,weak_ptr允许您访问对象,只要它存在,但“知道”对象何时不再存在,并且不允许您访问(如果已释放的)内存,如果对象曾经是对象已被摧毁。

Avoiding cycles depends on the sorts of things you're working with. 避免周期取决于您正在使用的各种事物。 If you deal with graphs a lot (for one example) they're often almost impossible to avoid, simply because quite a few things you model have cycles. 如果你经常处理图表(例如),他们通常几乎无法避免,只是因为你建模的东西有很多周期。 Otherwise, well...it depends. 否则,嗯......这取决于。 I'd guess a fair number of developers have gone for entire careers without ever having to create a linked structure that contains a cycle. 我猜想有相当数量的开发人员已经完成了整个职业生涯,而无需创建包含循环的链接结构。 Others probably do it several times in an average week. 其他人平均每周可能会多次这样做。

As far as other smart pointers go, as noted above the weak_ptr type works in conjunction with the shared_ptr; 就其他智能指针而言,如上所述,weak_ptr类型与shared_ptr一起使用; you can use shared_ptr without ever using a weak_ptr, but to make much real use of a weak_ptr at some point you have to convert it to a shared_ptr. 你可以在不使用weak_ptr的情况下使用shared_ptr,但是为了在某些时候真正使用weak_ptr,你必须将它转换为shared_ptr。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM