2013-08-05 5 views
12

क्यों सी नहीं ++ मानक स्मार्ट संकेत (unique_ptr, shared_ptr, ...) नियमित रूप से संकेत (टी *) से तुलना करने के लिए तुलना ऑपरेटरों शामिल होते हैं?नियमित सूचक के साथ स्मार्ट पॉइंटर की तुलना करने का कोई मानक तरीका नहीं है?

टॉम

अद्यतन मैं पता लगाने के लिए कि यह कैसे किया जा सकता है नहीं देख रहा हूँ। प्रश्न यह है कि इसे सी ++ मानक के हिस्से के रूप में क्यों परिभाषित नहीं किया जाता है? Unique_ptr और shared_ptr के लिए ऐसी परिभाषाएं छोटी होंगी। क्लास ए unique_ptr कुंजी के साथ एक नक्शा है:

इस के लिए एक उपयोग के मामले निम्नलिखित है। अद्वितीय प्रबंधन का उपयोग स्मृति प्रबंधन के लिए किया जाता है। जब कक्षा ए के उपयोगकर्ता ने नियमित पॉइंटर पास किया, तो इस मानचित्र के अंदर एक लुकअप किया जाता है। दुर्भाग्य से, मानक तुलना ऑपरेटर परिभाषित नहीं करता है।

+2

स्मार्ट पॉइंटर्स कच्चे पॉइंटर्स के समान नहीं हैं। नाशपाती के साथ सेब की तुलना क्यों करें? –

+1

@ टोनी थीलियन यह पता लगाने के लिए कि कौन सा अधिक स्वादिष्ट है, दुह।(संकेत: यदि यह वास्तव में एक अच्छा सेब है, तो नाशपाती पेंच) :) – jalf

+0

वैसे, भले ही उन तुलनाओं को संभव हो, फिर भी यह आपके विशेष उपयोग मामले को हल नहीं करेगा, जो 'std :: map द्वारा सीमित है ''इंटरफ़ेस और सामान्य रूप से कुंजी प्रकार के लिए अनुमति की तुलना में नहीं। एफवाईआई यह वही समस्या है (एक कच्चे सूचक के साथ 'std :: map ' खोज रहा है) हाल ही में यहां लाया गया है। –

उत्तर

14

क्यों नहीं सी ++ मानक स्मार्ट संकेत (unique_ptr, shared_ptr तुलना करने के लिए तुलना ऑपरेटरों में शामिल हैं, .. नियमित नियमित पॉइंटर्स (टी *) के साथ?

इस निर्णय के पीछे सिद्धांत आमतौर पर "गलत तरीके से उपयोग करने के लिए अपने इंटरफ़ेस को सही और कठिन/असंभव उपयोग करने में आसान" कहा जाता है।

वैचारिक रूप से, एक चतुर संकेतक और एक कच्चे सूचक ही नहीं हैं।

एक स्मार्ट सूचक प्रतिबंध लगाता है (यानी "unique_ptr एक सूचक है, लेकिन आपके पास एकाधिक प्रतियां नहीं हो सकती हैं")। यद्यपि वे पॉइंटर्स की तरह व्यवहार करते हैं (एक बिंदु पर - यदि आप पन क्षमा करेंगे), उनके पास अलग-अलग अर्थशास्त्र हैं।

यही है, यदि आपके पास:

int *p1 = new int{5}; 
std::unique_ptr<int> p2{new int{5}}; 

p1 == p2.get(); 

तुलना करने के लिए आसान है, स्पष्ट है, और यह स्पष्ट है कि आप सेब और सेब (समझने के लिए क्या हो रहा है आसान तुलना कर रहे हैं बनाता है - आप तुलना कर रहे हैं कच्चे सूचक के मूल्य के साथ)।

दूसरी ओर एक कस्टम तुलना ऑपरेटर होने से अजीब प्रश्न उठेंगे ("एक अद्वितीय_प्टर अद्वितीय है; आप इसे किसी और चीज़ से कैसे तुलना कर सकते हैं? - यदि यह अद्वितीय है, तो यह हमेशा अलग होना चाहिए")।

+1

"यदि यह अद्वितीय है, तो यह हमेशा अलग होना चाहिए" 'ऑटो और आरपी 0 = पी 2; ऑटो और आरपी 1 = पी 2; पी 1 == पी 2' (फ़ंक्शन पैरामीटर की कल्पना करें) ध्यान दें कि 'std :: unique_ptr' और अन्य 'unique_ptr' या' nullptr_t' के लिए तुलना ऑपरेटर हैं। पूर्व वास्तव में स्वामित्व वाले सूचक, यानी 'पी 2 == पी 2': <=>' p2.get() == p2.get() 'की तुलना करें, इसलिए तुलना 'p1 == p2.get()' अच्छी तरह से परिभाषित की जाएगी और आश्चर्य नहीं है। – dyp

+0

"अच्छी तरह से परिभाषित और आश्चर्यजनक नहीं होगा" - यह भाषा डिजाइनरों द्वारा अलग-अलग तरीकों से संबोधित एक पुरानी बहस है (यानी "ऑब्जेक्ट्स बराबर बनाम वस्तुओं के बराबर मान हैं"); जावा में, यह स्ट्रिंग तुलना समस्या का स्रोत है (आप 's1.compare (s2)' के साथ तारों की तुलना करते हैं, 's1 == s2' के साथ नहीं)। यदि आप 'std :: unique_ptr ' और 'T *' का उपयोग करके 'ऑपरेटर ==' बनाते हैं, तो आप अपने कोड के सभी क्लाइंट्स को अवधारणात्मक रूप से अलग करने में असमर्थ होने के लिए _force_ (क्योंकि उनके पास अलग-अलग प्रकार हैं), जब तक वे बदसूरत नहीं लिखते/इसके लिए त्रुटि प्रवण कोड (उदाहरण के लिए पहले प्रकार की तुलना)। – utnapistim

+0

मेरा मतलब था: 'ऑपरेटर ==' दो 'unique_ptr' के लिए पहले ही स्वामित्व वाले पॉइंटर्स के संदर्भ में परिभाषित किया गया है। इसलिए, कच्चे सूचक की तुलना अलग-अलग व्यवहार करने की आवश्यकता नहीं होगी। – dyp

8

तुम सिर्फ कर सकते हैं smart_ptr.get() == raw_ptr, क्या उस के साथ गलत क्या है?

+1

मुझे पता है कि काम करता है। मानक सीधे तुलना करने की अनुमति क्यों नहीं देता है? उदाहरण के लिए विचार करें, एक मानचित्र में देख रहे हैं जिसमें स्मार्ट पॉइंटर कुंजी प्रकार है। इसे ठीक से काम करने के लिए आपको अपने स्वयं के तुलनित्र को परिभाषित करने की आवश्यकता है। –

+0

यह मेरे लिए स्पष्टता जोड़ता है। इसे पढ़ना आसान है क्योंकि आपको उस जानकारी की आवश्यकता नहीं है। वैसे भी - अपने स्वयं के ऑपरेटर == को मुफ्त फ़ंक्शन के रूप में जोड़ना कोई समस्या नहीं होनी चाहिए। –

+3

@MasterT गलत सवाल। यह क्यों होना चाहिए –

4

क्योंकि तुलना ऑपरेटरों की तुलना नहीं है क्या करने के लिए, केवल वास्तविक सूचक बताया है। और चूंकि स्मार्ट पॉइंटर्स के पास वास्तविक कच्चे सूचक का "स्वामित्व" होता है, इसलिए कोई भी अन्य कच्चा सूचक तुलनात्मक स्मार्ट सूचक के समान नहीं हो सकता है।

+0

कच्चे पॉइंटर्स प्रोग्राम के कुछ हिस्सों द्वारा उपयोग/उपयोग किए जाने चाहिए जिन्हें वस्तु को जीवित रखने की आवश्यकता नहीं है। तुलना करते समय, क्या आप इस बात पर ध्यान देते हैं कि वस्तु को जीवित रखने वाले कौन रहता है? –

+1

@MasterT हां बिल्कुल आप करते हैं। अन्यथा स्मार्ट पॉइंटर्स का उपयोग क्यों करें? बेशक विभिन्न परिचालनों को समानता के विभिन्न अर्थों की आवश्यकता होती है। लेकिन * सामान्य * अर्थ निश्चित रूप से स्वामित्व (और संभावित रूप से हटाना) के लिए जिम्मेदार होना चाहिए। –

+0

@ कोनराड रुडॉल्फ स्मार्ट पॉइंटर्स की तुलना करते समय स्वामित्व और डिलीटर को ध्यान में क्यों रखा जाना चाहिए? स्वामित्व कब हटाना है और हटाए जाने वाले लोगों को हटाने के बारे में है। मेरी राय में, हटाने और तुलना करने के बीच कोई अर्थपूर्ण संबंध नहीं है। –

1

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

+0

यदि कार्यक्रम के एक हिस्से को वस्तुओं के जीवनकाल के बारे में जानने की आवश्यकता नहीं है, तो मैं कक्षा इंटरफेस में नियमित पॉइंटर्स का उपयोग करता हूं। Http://stackoverflow.com/questions/7657718/when-to-use-shared-ptr-and-when-to-use-raw-pointers –

+3

बस घर को हथौड़ा दें कि कोई भी कच्चा सूचक गैर-स्वामित्व वाला है, यह होना चाहिए सी ++ 11 के साथ उनके बारे में डिफ़ॉल्ट धारणा। – Xeo

+0

@Xeo सामान्य मामला यह है कि कोई मालिकाना पॉइंटर्स नहीं है, और किसी स्मार्ट पॉइंटर्स के लिए कोई उपयोग नहीं है। किसी भी चीज के मालिक के बारे में बहुत ही अवधारणा थोड़ा अजीब है; पॉइंटर्स बहुत कम स्तर की वस्तुएं हैं, वास्तविक व्यवहार या जिम्मेदारियों के साथ। अधिकांश अनुप्रयोगों के पास किसी भी स्मार्ट पॉइंटर्स के लिए कोई उपयोग नहीं होगा। दूसरी तरफ, 'std :: shared_ptr' और कच्चे पॉइंटर्स को मिलाकर आपदा के लिए एक नुस्खा है। यदि आप 'std :: shared_ptr' का उपयोग कर रहे हैं, तो आपके पास ऑब्जेक्ट का कच्चा सूचक नहीं होना चाहिए (जिसका अर्थ है कि कोई सदस्य कार्य नहीं है, क्योंकि यह 'कच्चा सूचक है)। –

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