AFAIK,通常不鼓励使用 shared_ptr,因为不小心使用它们会导致潜在的错误(除非你对显着的好处和仔细检查的设计有很好的解释)。
另一方面,Python 对象似乎本质上是 shared_ptrs(ref_count 和垃圾收集)。
我想知道是什么让它们在 Python 中运行良好,但在 C++ 中可能存在危险。换句话说,Python 和 C++ 在处理 shared_ptr 方面有什么区别,这使得它们在 C++ 中不鼓励使用但在 Python 中不会引起类似问题?
我知道例如Python 会自动检测对象之间的循环,从而防止在 C++ 中可能导致悬空循环 shared_ptrs 的内存泄漏。
最佳答案
“我知道例如 Python 会自动检测循环”——这就是让它们很好地工作的原因,至少就与内存泄漏相关的“潜在错误”而言。
除此之外,与 Python 程序相比,C++ 程序更常在严格的性能约束下编写(IMO 是不同真实需求的组合,但在经验法则上存在一些相当虚假的差异,但那是另一回事)。我使用的大部分 Python 对象并不严格需要引用计数,它们只有一个所有者和一个 unique_ptr
会很好(或者就此而言是类类型的数据成员)。在 C++ 中,它被认为(由编写您正在阅读的建议的人)值得利用性能优势和明确简化的设计。在 Python 中,它通常不被认为是一个问题,您为性能付出代价,并且您可以灵活地稍后决定是否共享它,而无需更改任何代码(我的意思是,除了获取比原始文件生命周期更长的其他引用之外)。
顺便说一句,在任何语言中,共享可变对象都有与之相关的“潜在错误”,如果您在不查看对象时忘记了哪些对象会发生变化或不会发生变化。我不仅仅是指竞争条件:即使在单线程程序中,您也需要意识到 C++ 谓词不应更改任何内容,并且您(通常)不能在迭代容器时对其进行变异。不过,我不认为这是 C++ 和 Python 之间的区别。相反,在某种程度上,您也应该对 Python 中的共享对象稍加警惕,并且当您对对象的引用激增时,至少要了解您为什么要这样做。
因此,转到您链接到的问题中的问题列表:
shared_ptr
s to the same object -- 在 Python 中不可能有类似的东西,因为引用计数器不对用户开放以搞乱。 get()
function to get the raw pointer and use it after the pointed-to object goes out of scope -- 好吧,如果您正在编写 Python/C,但不是在纯 Python 中,您可能会搞砸。 shared_ptr
需要的时候。不能在 Python 中做到这一点。 <functional>
don't play nicely with shared_ptr
-- Python refcounting 内置于运行时中(或者我想准确地说我应该说:垃圾收集内置于语言设计中)以至于没有任何库无法应对它。 numpy
以减少开销。有时 Python 程序内存不足,您需要对此做点什么,这就是生活;-) shared_ptr< T >
to this inside a class definition is also dangerous. Use enabled_shared_from_this
instead -- 这可能不是很明显,但这又是“不要为同一个对象创建多个不相关的 shared_ptr
”。 shared_ptr
in multithread code -- 也可以在 Python 中创建竞争条件,这是“共享可变对象很棘手”的一部分。 这主要是因为在 C++ 中你必须明确地做一些事情来获得 refcounting,如果你不要求它,你就不会得到它。这提供了多种出错机会,而 Python 不会提供给程序员,因为它只是为你做的。如果您使用
shared_ptr
正确然后除了不与它合作的库的存在之外,这些问题也没有出现在 C++ 中。那些因为这些原因而谨慎使用它的人基本上是在说他们害怕他们会错误地使用它,或者至少比他们会滥用某些替代品更害怕。大部分 C++ 编程都在相互交换不同的潜在错误,直到您提出一个您认为自己有能力执行的设计。此外,它还将“不要为不需要的东西付费”作为设计理念。在这两个因素之间,如果没有很好的解释、显着的好处和仔细检查的设计,你就不会做任何事情。 shared_ptr
没有什么不同;-)
关于python - C++ shared_ptr 与 Python 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32362884/