निर्णय लेना कि स्मार्ट पॉइंटर का उपयोग करना स्वामित्व का सवाल है । जब यह संसाधन प्रबंधन की बात आती है, तो वस्तु ए, वस्तु बी का मालिक है यदि यह वस्तु बी के जीवनकाल के नियंत्रण में है। उदाहरण के लिए, सदस्य चर का स्वामित्व उनकी संबंधित वस्तुओं के पास होता है क्योंकि सदस्य चर का जीवनकाल वस्तु के जीवनकाल से बंधा होता है। आप स्मार्ट पॉइंटर्स चुनते हैं जो ऑब्जेक्ट के स्वामित्व में है।
ध्यान दें कि सॉफ़्टवेयर सिस्टम में स्वामित्व स्वामित्व से अलग है क्योंकि हम सॉफ़्टवेयर के बाहर इसके बारे में सोचेंगे। उदाहरण के लिए, एक व्यक्ति अपने घर को "खुद" कर सकता है, लेकिन इसका मतलब यह नहीं है कि किसी Person
वस्तु का जीवनकाल पर नियंत्रण होता है House
। सॉफ्टवेयर अवधारणाओं के साथ इन वास्तविक दुनिया की अवधारणाओं को जोड़ना अपने आप को एक छेद में प्रोग्राम करने का एक निश्चित तरीका है।
यदि आपके पास ऑब्जेक्ट का एकमात्र स्वामित्व है, तो उपयोग करें std::unique_ptr<T>
।
यदि आपने वस्तु का स्वामित्व साझा किया है ...
- यदि स्वामित्व में कोई चक्र नहीं हैं, तो उपयोग करें std::shared_ptr<T>
।
- यदि चक्र हैं, तो एक "दिशा" को परिभाषित करें std::shared_ptr<T>
और एक दिशा std::weak_ptr<T>
में और दूसरे में उपयोग करें ।
यदि ऑब्जेक्ट आपके पास है, लेकिन कोई मालिक नहीं होने की संभावना है, तो सामान्य पॉइंटर्स T*
(जैसे पैरेंट पॉइंटर्स) का उपयोग करें।
यदि ऑब्जेक्ट आपके पास है (या अन्यथा अस्तित्व की गारंटी है), तो संदर्भ का उपयोग करें T&
।
कैविएट: स्मार्ट पॉइंटर्स की लागतों से अवगत रहें। स्मृति या प्रदर्शन सीमित वातावरण में, स्मृति के प्रबंधन के लिए अधिक मैनुअल योजना के साथ सामान्य बिंदुओं का उपयोग करना फायदेमंद हो सकता है।
मूल्य:
- यदि आपके पास एक कस्टम डिलेटर है (जैसे आप आवंटन पूल का उपयोग करते हैं) तो यह प्रति सूचक ओवरहेड को उकसाएगा जिसे मैन्युअल रूप से हटाने से आसानी से बचा जा सकता है।
std::shared_ptr
कॉपी पर एक रेफरेंस काउंट इन्क्रीमेंट का ओवरहेड है, साथ ही विनाश पर एक डिक्लेरेशन है जिसके बाद रखी गई ऑब्जेक्ट को हटाने के साथ 0-काउंट की जांच होती है। कार्यान्वयन के आधार पर, यह आपके कोड को ब्लोट कर सकता है और प्रदर्शन समस्याओं का कारण बन सकता है।
- संकलन समय। सभी टेम्प्लेट की तरह, स्मार्ट पॉइंटर्स समय को संकलित करने में नकारात्मक योगदान देते हैं।
उदाहरण:
struct BinaryTree
{
Tree* m_parent;
std::unique_ptr<BinaryTree> m_children[2]; // or use std::array...
};
एक द्विआधारी वृक्ष का अपना माता-पिता नहीं होता है, लेकिन एक पेड़ का अस्तित्व उसके माता-पिता (या nullptr
जड़ के लिए) के अस्तित्व को दर्शाता है , जिससे कि एक सामान्य सूचक का उपयोग किया जाता है। एक बाइनरी ट्री (मूल्य शब्दार्थ के साथ) अपने बच्चों का एकमात्र स्वामित्व है, इसलिए वे हैं std::unique_ptr
।
struct ListNode
{
std::shared_ptr<ListNode> m_next;
std::weak_ptr<ListNode> m_prev;
};
यहां, सूची नोड अपनी अगली और पिछली सूचियों का स्वामी है, इसलिए हम चक्र को तोड़ने के लिए एक दिशा और shared_ptr
अगले के लिए उपयोग weak_ptr
करते हैं।