简体   繁体   English

将shared_ptr与托管语言引用进行比较

[英]Comparing shared_ptr to managed language references

Could someone explain to a C++ programmer most important differences between Java (and C# as well) references and shared_ptr (from Boost or from C++0x). 有人可以向C ++程序员解释Java(和C#)引用和shared_ptr(来自Boost或来自C ++ 0x)之间最重要的区别。

I more or less aware how shared_ptr is implemented. 我或多或少知道如何实现shared_ptr。 I am curious about differences in the following ares: 我很好奇以下几个方面的差异:

1) Performance. 1)表现。 2) Cycling. 2)骑自行车。 shared_ptr can be cycled (A and B hold pointers to each other). shared_ptr可以循环(A和B保持彼此的指针)。 Is cycling possible in Java? 在Java中可以骑自行车吗? 3) Anything else? 3)还有别的吗?

Thank you. 谢谢。

Performance : shared_ptr performs pretty well, but in my experience is slightly less efficient than explicit memory management, mostly because it is reference counted and the reference count has to allocated as well. 性能shared_ptr表现相当不错,但根据我的经验,效率略低于显式内存管理,主要是因为它是引用计数,并且引用计数也必须分配。 How well it performs depends on a lot of factors and how well it compares to Java/C# garbage collectors can only be determined on a per use case basis (depends on language implementation among other factors). 它的执行效果取决于很多因素,它与Java / C#垃圾收集器的比较只能根据每个用例来确定(取决于语言实现和其他因素)。

Cycling is only possible with weak_ptr , not with two shared_ptr s. 只能使用weak_ptr 循环 ,而不能使用两个shared_ptr Java allows cycling without further ado; Java允许骑自行车而不用再费力; its garbage collector will break the cycles . 它的垃圾收集器将打破周期 My guess is that C# does the same. 我的猜测是C#做的一样。

Anything else : the object pointed to by a shared_ptr is destroyed as soon as the last reference to it goes out of scope. 其他任何事情 :一旦shared_ptr指向的对象在最后一次引用超出范围时就被销毁。 The destructor is called immediately. 析构函数立即被调用。 In Java, the finalizer may not be called immediately. 在Java中,可能不会立即调用终结器。 I don't know how C# behaves on this point. 我不知道C#在这一点上的表现如何。

The key difference is that when the shared pointer's use count goes to zero, the object it points to is destroyed (destructor is called and object is deallocated), immediately. 关键的区别在于,当共享指针的使用计数变为零时,它指向的对象将被立即销毁(析构函数被调用,对象被释放)。 In Java and C# the deallocation of the object is postponed until the Garbage Collector chooses to deallocate the object (ie, it is non-deterministic). 在Java和C#中,对象的释放被推迟,直到垃圾收集器选择解除分配对象(即,它是非确定性的)。

With regard to cycles, I am not sure I understand what you mean. 关于周期,我不确定我明白你的意思。 It is quite common in Java and C# to have two objects that contain member fields that refer to each other, thus creating a cycle. 在Java和C#中,有两个对象包含相互引用的成员字段,从而创建一个循环。 For example a car and an engine - the car refers to the engine via an engine field and the engine can refer to its car via a car field. 例如汽车和发动机 - 汽车通过发动机领域引用发动机,发动机可以通过汽车领域参考其汽车。

Cyclical references with C++ reference-counted pointers will not be disposed. 使用C ++引用计数指针的循环引用将不会被处理。 You can use weak pointers to work around this. 你可以使用弱指针来解决这个问题。 Cyclical references in Java or C# may be disposed, when the garbage collector feels like it. 当垃圾收集器感觉像它时,可以处理Java或C#中的循环引用。

When the count in a C++ reference-counted pointer drops to zero, the destructor is called. 当C ++引用计数指针中的计数降为零时,将调用析构函数。 When a Java object is no longer reachable, its finalizer may not be called promptly or ever. 当Java对象不再可访问时,可能无法立即或永远调用其终结器。 Therefore, for objects which require explicit disposal of external resources, some form of explicit call is required. 因此,对于需要显式处理外部资源的对象,需要某种形式的显式调用。

First of all, Java/C# have only pointers, not references, though they call them that way. 首先,Java / C#只有指针,而不是引用,尽管它们以这种方式调用它们。 Reference is a unique C++ feature. Reference是一种独特的C ++功能。 Garbage collection in Java/C# basically means infinite life-time. Java / C#中的垃圾收集基本上意味着无限的生命周期。 shared_ptr on the other hand provides sharing and deterministic destruction, when the count goes to zero. 另一方面, shared_ptr在计数变为零时提供共享和确定性破坏。 Therefore, shared_ptr can be used to automatically manage any resources, not just memory allocation. 因此, shared_ptr可用于自动管理任何资源,而不仅仅是内存分配。 In a sense (just like any RAII design) it turns pointer semantics into more powerful value semantics. 从某种意义上说(就像任何RAII设计一样)它将指针语义转换为更强大的价值语义。

Nobody pointed the possibility of moving the object by the memory manager in managed memory. 没有人指出由内存管理器在托管内存中移动对象的可能性。 So in C# there are no simple references/pointers, they work like IDs describing object which is returned by the manager. 所以在C#中没有简单的引用/指针,它们的工作方式类似于描述管理器返回的对象的ID。
In C++ you can't achieve this with shared_ptr, because the object stays in the same location after it has been created. 在C ++中,您无法使用shared_ptr实现此目的,因为对象在创建后仍保留在同一位置。

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

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