另外,由于不小心使用shared-ptr会导致潜在的错误,所以通常不鼓励使用shared-ptr(除非您对显著的好处有很好的解释,并且仔细检查了设计)。在
另一方面,Python对象似乎本质上是共享的(ref_count和垃圾回收)。在
我想知道是什么让它们在Python中工作得很好,但是C++中有潜在的危险。换句话说,Python和C++在处理SyddypTr时有什么不同,它们使得它们在C++中的使用受到了阻碍,但在Python中没有引起类似的问题?在我知道,例如Python自动检测对象之间的周期,防止了循环SydDypRTs会导致C++中的内存泄漏。在
“我知道,例如Python会自动检测到循环”,这是它们工作得很好的原因,至少就“潜在的bug”与内存泄漏相关而言。在
除此之外,C++程序比Python程序更能在严格的性能约束下编写(IMO是不同的真正要求的结合,在拇指规则上有一些相当虚假的差异,但这是另一个故事)。我使用的Python对象中有相当高的一部分严格来说不需要引用计数,它们只有一个所有者,
unique_ptr
就可以了(或者说是类类型的数据成员)。在C++中,(人们写的建议)值得考虑性能优势和明确简化的设计。在Python中,它通常不被认为是一个问题,您可以支付性能,并保留以后决定共享它的灵活性,而不需要任何代码更改(我的意思是,除了获取比原始版本更长的引用之外)。在顺便说一句,在任何语言中,共享的可变对象都有与之相关的“潜在bug”,如果你不去看那些对象,它们会或不会改变。我不仅仅是指竞争条件:即使在一个线程程序中,你也需要意识到C++谓词不应该改变任何东西,而且你(经常)不能在迭代容器时对其进行突变。不过,我不认为这是C++和Python之间的区别。相反,在某种程度上,您也应该对Python中的共享对象保持一点警惕,当您大量引用一个对象时,至少应该理解您为什么要这样做。在
因此,在您链接到的问题列表中:
- cyclic references如前所述,Python卷起袖子,找到它们并释放它们。由于与语言的设计和特定用途有关,循环中断垃圾收集在C++中是很难实现的,虽然不是不可能的。在
- creating multiple unrelated ^{
}s to the same object 在Python中不可能进行模拟,因为引用计数器不会对用户开放以使其混乱。在 - Constructing an anonymous temporary shared pointer不会出现在Python中,因此在Python中没有内存泄漏的风险,因为对象不存在“间隙”,但如果对象未被引用,则还不受收集的影响。在
- Calling the ^{
} function to get the raw pointer and use it after the pointed-to object goes out of scope 好吧,如果你在写Python/C,但不是用纯Python编写,你可能会把事情搞砸。在 - Passing a reference of or a raw pointer to a shared_ptr should be dangerous too, since it won't increment the internal count在Python中,如果语言不负责refcount,就无法添加引用。在
- we passed 'this' to some thread workers instead of 'shared_from_this'换句话说,在需要时忘记创建{
}。在Python中不能这样做。在 - most of the predicates you know and love from ^{
} don't play nicely with ^{} Python refcounting是如此内置于运行时中(或者我想确切地说,垃圾收集是如此内置于语言设计中),以至于没有库无法处理它。在 - Using shared_ptr for really small objects (like char short) could be an overhead问题在Python中存在,Python程序员通常不会担心这个问题。如果您需要一个“primitive type”数组,那么可以使用
- Giving out a ^{
} to this inside a class definition is also dangerous. Use ^{} instead 这可能不明显,但这又是“不要为同一对象创建多个无关的 - You need to be careful when you use ^{
} in multithread code 在Python中也可以创建竞争条件,这是“共享可变对象很诡诈”的一部分。在
大部分的事情是这样的:在C++中,你必须明确地做一些事情来获得重新计数,如果你不要求它,你就得不到它。这为程序员提供了一些错误的机会,因为Python只是为您而做的。如果你使用了^ {CD2}},那么除了不存在与它合作的库的存在之外,这些问题也没有出现在C++中。那些出于这些原因而谨慎使用它的人,基本上是说他们害怕他们会错误地使用它,或者至少更害怕他们会误导我们有别的选择。C++编程中的大部分都是将不同的潜在错误相互交易,直到你想出一个你认为自己有能力执行的设计。此外,它还把“不需要的东西不付钱”作为一种设计理念。在这两个因素之间,如果没有一个很好的解释、一个显著的好处和一个经过仔细检查的设计,你不会做任何事情。numpy
来减少开销。有时Python程序内存不足,您需要对此做些什么,这就是生命;-)shared_ptr
”。在shared_ptr
没有什么不同;-)我不同意。除非你有很好的理由不这么做,否则一般倾向于使用这些智能指针。在
好吧,我不知道您最喜欢的更大的信号处理框架生态系统,但是GNU Radio对所有的块使用共享的ptr,这是GNU无线电架构的核心元素。实际上,块是带有
private
构造函数的类,这些构造函数只能由friend
make
函数访问,该函数返回shared_ptr
。我们在这方面没有问题,GNU电台有充分的理由采用这种模式。现在,我们没有一个地方可以让用户尝试使用释放的块对象,没有一个块被泄露。不错!在也可以使用SWIG和一些C++类的网关类,它们不能很好地表示为Python类型。所有这些在两方面都很好,C++和Python。事实上,它工作得非常好,我们可以在PythDypTR中使用Python类作为C++运行时中的块。在
而且,我们从来没有性能问题。GNU无线电是一个高速率、高度优化、大量多线程的框架。在
相关问题 更多 >
编程相关推荐