2014-11-06 5 views
6

से कच्चे सूचक को रिसाव करने के लिए पोर्टेबल हैक मेरे पास ऑब्जेक्ट संरचना है जो shared_ptr एस, प्लस weak_ptr एस परिपत्र से बचने के लिए बनाई गई है। कच्चे पॉइंटर्सboost::serialization को क्रमबद्ध और कमजोर पॉइंटर्स को पुनर्स्थापित करने की आवश्यकता है जब ऑब्जेक्ट ट्रैकिंग के माध्यम से क्रमबद्धता समय के रूप में deserializing। ऑब्जेक्ट आजीवन पैटर्न जटिल (कण सिमुलेशन) हैं लेकिन पूरी तरह अनुमानित हैं। जब भी मैं weak_ptr::lock() का उपयोग करता हूं, मुझे यकीन है कि सूचक अभी भी मान्य है। आम तौर पर, मैं lock().get() का उपयोग करता हूं क्योंकि मुझे केवल बहुत ही कम समय के लिए ऑब्जेक्ट की आवश्यकता होती है।पोर्टेबल हैक कमजोर_पीआरआर

अब, lock().get() के रूप में यह साझा गिनती में वृद्धि करेगा (lock() में), और फिर इसे शीघ्र ही बाद में घटती (अस्थायी shared_ptr विलुप्त है) प्रदर्शन प्रभाव पड़ता है,।

यह boost.devel post 2002 से कहते हैं कि जब तक weak_ptr विकसित किया जा रहा था, कच्चे सूचक सीधे माना जाता था तक पहुँचने की कार्यक्षमता (unsafe_get या leak नामित किया जाना है), लेकिन वास्तविक क्रियान्वयन के लिए इसे बनाया कभी नहीं। इसकी अनुपस्थिति प्रोग्रामर को दी गई स्थितियों के तहत उप-स्थानिक इंटरफ़ेस का उपयोग करने के लिए मजबूर करती है।

अब, सवाल unsafe_get/leak अनुकरण करने के लिए कैसे, एक और शब्दों में,, weak_ptr से कच्चे सूचक मिल प्रोग्रामर के जोखिम पर अवैध, केवल (नहीं लिख) डाटा पढ़ने है। मैं कल्पना कर सकता हूं कि कुछ चालबाजी shared_ptr के अंदर कच्चे सूचक के ऑफसेट को खोजने की तरह है या ऐसा काम करेगा।

मैं boost::shared_ptr का उपयोग कर रहा हूं, लेकिन समाधान सी ++ 11 के std::shared_ptr के लिए भी काम कर सकता है।

+2

अच्छा सवाल है लेकिन यह ईमानदारी से कच्चे पॉइंटर्स की तरह लगता है कि यह बेहतर सौदा होगा। वस्तुओं को अलग से प्रबंधित करें (उदा। अपने सभी कणों को एक कंटेनर में पूल करें) और उन लोगों को कमजोर पॉइंटर्स पास करें। –

+0

मुझे लगता है कि यदि आप केवल थोड़े समय के लिए ऑब्जेक्ट का उपयोग कर रहे हैं, तो आप इसे इस्तेमाल करते समय 'shared_ptr' रखना चाहिए:' auto s = w.lock(); अगर (एस) एस-> कुछ करना(); 'मुझे लगता है कि' लॉक() का उपयोग करना।() 'खराब अभ्यास है और कोई तेज़ नहीं है। यह संभव है कि सूचक का उपयोग करने की बहुत ही क्रिया वास्तव में अंतिम 'shared_ptr' मरने के लिए ट्रिगर कर सकती है। –

+1

यदि आप वस्तुओं के जीवनकाल को '.lock()' के बिना कमजोर इंगित करते हैं, तो 'weak_ptr' का उपयोग न करें। क्या आपने साबित किया है कि यह एक तरफ एक प्रदर्शन बाधा है? – Yakk

उत्तर

3

मेरा सुझाव है कि आप बस weak_ptr और कच्चे सूचक दोनों को पकड़ें और कच्चे सूचक को सीधे अनुकूलन के रूप में उपयोग करें जब आपको पता है कि ऐसा करना सुरक्षित है। आप weak_ptr और उस श्रेणी में कच्चे सूचक को जोड़ सकते हैं जिसमें unsafe_get है यदि आप चाहें।

+1

एक प्रासंगिक नोट यह है कि यह सी ++ 11 के बाद से कच्चे पॉइंटर्स और संदर्भों के आस-पास स्टोर, उपयोग और पास करने के लिए पूरी तरह से मान्य है, क्योंकि उन पॉइंटर्स को ऑब्जेक्ट के जीवनकाल को "स्वयं" या प्रबंधित नहीं किया जाता है - सुरक्षा के लिए नियम यह है कि आपको पता होना चाहिए कि कुछ "मालिक" (जैसे कि एक ही ऑब्जेक्ट में 'shared_ptr') उन्हें बहिष्कृत करता है। बेशक एक 'weak_ptr' उस ऑब्जेक्ट का स्वामित्व नहीं रखता है, इसलिए वहां संभावित समस्याएं हैं यदि आप उस ऑब्जेक्ट के जीवनकाल के बारे में सुनिश्चित नहीं हो सकते हैं - क्या यह संभव है कि कोई अन्य कोड अंतिम 'shared_ptr' को नष्ट कर सके 'weak_ptr'-संदर्भित ऑब्जेक्ट? – Steve314

+1

इसमें कोई संदेह नहीं है कि मानक में 'unsafe_lock' नहीं है। 'लॉक() का उपयोग करना। (प्राप्त करें) (यानी जब तक आप कच्चे सूचक का उपयोग नहीं कर रहे हैं तब तक' shared_ptr' को नहीं रखना) बहुत कमजोर है। – Steve314

+0

@ स्टीव 314: ओटी: मुझे नहीं लगता कि यह संभव खतरों के कारण एक को प्रतिबंधित करने के लिए सी ++ का व्यवसाय है। मैं मानता हूं कि खतरनाक प्रथाओं को प्रोत्साहित करना अच्छा नहीं है, लेकिन इसमें कुछ शामिल नहीं है क्योंकि ** ** ** का दुरुपयोग किया जा सकता है, यह थोड़ा सा parenting है। – eudoxos

5

चूंकि आपने पोर्टेबल हैक के लिए कहा था।

boost's weak_ptr.hpp में पाया कोड का एक अजीब हिस्सा है:

template<class T> class weak_ptr 
{ 
    ... 

public: 

    ... 

// Tasteless as this may seem, making all members public allows member templates 
// to work in the absence of member template friends. (Matthew Langston) 

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 

private: 

    template<class Y> friend class weak_ptr; 
    template<class Y> friend class shared_ptr; 

#endif 

    element_type * px;   // contained pointer 
    boost::detail::weak_count pn; // reference counter 

}; // weak_ptr 

अगर आप BOOST_NO_MEMBER_TEMPLATE_FRIENDS विकल्प के साथ बढ़ावा संकलन जिसका मतलब है, आप सार्वजनिक रूप से सदस्य weak_ptr की px जो एक कच्चे सूचक हो रहा है के लिए उपयोग होगा तत्व प्रकार के लिए।

+1

मुझे यकीन नहीं है कि यह भविष्य के सबूत कैसे है ... भावी रिलीज में बाइनरी संगतता को तोड़ने के बारे में बूस्ट की नीति क्या है? क्योंकि अगर वे इसे (बहुत मान्य) की अनुमति देते हैं तो दुर्भाग्य से यह हैक पोर्टेबल नहीं है। और यह 'std :: weak_ptr' के साथ भी काम नहीं करेगा। –

+1

@ कोनराड रुडॉल्फ ठीक है अगर यह भविष्य के सबूत था तो यह एक हैक नहीं होगा। लेकिन किसी दिए गए समय पर यह हैक बूस्ट लाइब्रेरीज़ के रूप में पोर्टेबल है, यह केवल तब ही टूट सकता है जब आप अपने बूस्ट संस्करण को अपग्रेड करते हैं, लेकिन किसी अन्य सामान्य सुविधा को बढ़ावा देने से भी कर सकते हैं। – Drax

+0

एक और विकल्प दोस्ती का लाभ उठाने के लिए हो सकता है: एक विशेष रूप से नामित प्रकार वाई का उपयोग करके एक कमजोर_पीआरआर को स्पष्ट रूप से विशेषज्ञ बनाएं, और उसके बाद पीएक्स का उपयोग करें: 'टेम्पलेट <> weak_ptr {/ * weak_ptr * /} का दोस्त; '। टेम्पलेट मित्र एक सामान्य पहुंच बैकडोर है। – NicholasM

संबंधित मुद्दे