[英]C++ shared_ptr vs. Python object
AFAIK,使用shared_ptr通常是不鼓勵的,因為不小心使用它們會導致潛在的錯誤(除非您對重大利益和仔細檢查設計有非常好的解釋)。
另一方面,Python對象似乎基本上是shared_ptrs(ref_count和垃圾收集)。
我想知道是什么讓它們在Python中很好地工作但在C ++中有潛在危險。 換句話說,Python和C ++在處理shared_ptr時有什么區別,這使得在C ++中不鼓勵使用它們但不會在Python中引起類似的問題?
我知道,例如Python會自動檢測對象之間的循環,以防止在C ++中懸掛循環shared_ptrs導致的內存泄漏。
“我知道,例如Python會自動檢測周期” - 這就是讓它們很好地工作的原因,至少就“潛在的錯誤”與內存泄漏有關。
除此之外,C ++程序通常在嚴格的性能限制下編寫而不是Python程序(IMO是不同真實要求的組合,在經驗法則方面有一些相當虛假的差異,但這是另一個故事)。 我使用的相當大比例的Python對象並不嚴格需要引用計數,它們只有一個所有者,而unique_ptr
就可以了(或者unique_ptr
類類型的數據成員)。 在C ++中,(由人們撰寫您正在閱讀的建議)可以考慮采用性能優勢和明確簡化的設計。 在Python中,它通常不被認為是一個問題,你付出了性能,你可以保持靈活性,以便稍后決定它是否共享,而不需要任何代碼更改(除了采取比原始版本更長的其他引用,我的意思)。
順便說一句,在任何語言中,共享的可變對象都有與它們相關的“潛在錯誤”,如果你在沒有看到它們時忘記了哪些對象會改變或不改變。 我不僅僅意味着競爭條件:即使在單線程程序中,您也需要注意C ++ Predicates不應該改變任何東西,並且您(通常)在迭代它時不能改變容器。 不過,我不認為這是C ++和Python之間的區別。 相反,在某種程度上,你也應該對Python中的共享對象略微保持警惕,並且當你擴展對象的引用時至少理解為什么要這樣做。
那么,關於您鏈接到的問題中的問題列表:
shared_ptr
到同一個對象 - 在Python中沒有模擬可能,因為引用計數器不對用戶開放。 get()
函數來獲取原始指針並在指向對象超出范圍之后使用它 - 好吧,如果你正在編寫Python / C而不是純Python,你可以搞砸它。 shared_ptr
。 不能用Python做到這一點。 <functional>
大多數謂詞都不能很好地與shared_ptr
- Python引用計數內置於運行時(或者我認為應該說是精確的:垃圾收集內置於語言中設計)沒有圖書館無法應對它。 numpy
來減少開銷。 有時Python程序內存耗盡,你需要對它做一些事情,這就是生活;-) shared_ptr< T >
也是危險的。 使用enabled_shared_from_this
- 它可能不是很明顯,但這是“不要再為同一個對象創建多個不相關的shared_ptr
”。 shared_ptr
時需要小心 - 也可以在Python中創建競爭條件,這是“共享可變對象很棘手”的一部分。 其中大部分都是因為在C ++中你必須明確地做一些事情才能得到引用計數,而如果你不要求它就不能得到它。 這提供了幾個Python無法提供給程序員的錯誤機會,因為它只是為您完成。 如果正確使用shared_ptr
,那么除了不與它合作的庫的存在之外,C ++中也不會出現這些問題。 那些因為這些原因而謹慎使用它的人基本上都說他們害怕他們會錯誤地使用它,或者無論如何更害怕他們會誤用某些替代品。 在你想出一個你認為自己有能力執行的設計之前,很多C ++編程都會互相交換不同的潛在錯誤。 此外,作為一種設計理念,它“不為你不需要的東西買單”。 在這兩個因素之間,如果沒有一個非常好的解釋,一個顯着的好處和一個經過仔細檢查的設計,你就不會做任何事情 。 shared_ptr
沒有什么不同;-)
AFAIK,使用shared_ptr通常是不鼓勵的,因為不小心使用它們會導致潛在的錯誤(除非您對重大利益和仔細檢查設計有非常好的解釋)。
我不同意。 除非你有充分的理由不這樣做,否則傾向於普遍使用這些智能指針。
shared_ptr使得在C ++中不鼓勵使用它們但不會在Python中引起類似的問題?
好吧,我不知道你最喜歡的大型信號處理框架生態系統,但GNU Radio使用shared_ptrs來處理所有塊 ,這是GNU Radio架構的核心元素。 實際上,塊是具有private
構造函數的類,只能由friend
make
函數訪問,該函數返回shared_ptr
。 我們沒有遇到過這樣的問題--GNU Radio有充分的理由采用這種模式。 現在,我們沒有一個用戶嘗試使用解除分配的塊對象的地方,而不是泄漏單個塊。 太好了!
此外,我們使用SWIG和一個網關類來處理一些C ++類型,這些類型不能像Python類型那樣很好地表示。 所有這些在雙方都很有效,C ++和Python。 實際上,它運行得非常好,我們可以將Python類用作C ++運行時中的塊,包含在shared_ptr中。
此外,我們從未遇到過性能問題。 GNU Radio是一個高速率,高度優化,多線程的框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.