स्मार्ट पॉइंटर क्या है और मुझे कब इस्तेमाल करना चाहिए?
स्मार्ट पॉइंटर क्या है और मुझे कब इस्तेमाल करना चाहिए?
जवाबों:
अपडेट करें
यह उत्तर पुराना है, और इसलिए वर्णन करता है कि उस समय क्या 'अच्छा' था, जो बूस्ट लाइब्रेरी द्वारा प्रदान किए गए स्मार्ट पॉइंटर्स थे। C ++ 11 के बाद से, मानक पुस्तकालय ने पर्याप्त स्मार्ट पॉइंटर्स प्रकार प्रदान किए हैं, और इसलिए आपको इसके उपयोग का पक्ष लेना चाहिए std::unique_ptr
, std::shared_ptr
और std::weak_ptr
।
भी था std::auto_ptr
। यह एक स्कोप्ड पॉइंटर की तरह बहुत अधिक था, सिवाय इसके कि इसमें "विशेष" खतरनाक नकल करने की क्षमता भी थी - जो अप्रत्याशित रूप से स्वामित्व को स्थानांतरित करता है।
इसे C ++ 11 में हटा दिया गया था और C ++ 17 में हटा दिया गया था , इसलिए आपको इसका उपयोग नहीं करना चाहिए।
std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership.
// p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.
पुराने ANSWER
एक स्मार्ट पॉइंटर एक ऐसा वर्ग है जो इंगित किए गए ऑब्जेक्ट के जीवनकाल को प्रबंधित करने के लिए एक 'रॉ' (या 'नंगे') C ++ पॉइंटर को लपेटता है। एक भी स्मार्ट पॉइंटर प्रकार नहीं है, लेकिन ये सभी एक कच्चे पॉइंटर को एक व्यावहारिक तरीके से अमूर्त करने की कोशिश करते हैं।
कच्चे पॉइंटर्स पर स्मार्ट पॉइंटर्स को प्राथमिकता दी जानी चाहिए। यदि आपको लगता है कि आपको पॉइंटर्स का उपयोग करने की आवश्यकता है (पहले विचार करें कि क्या आप वास्तव में करते हैं), तो आप सामान्य रूप से एक स्मार्ट पॉइंटर का उपयोग करना चाहते हैं क्योंकि यह कच्चे पॉइंटर्स के साथ कई समस्याओं को दूर कर सकता है, मुख्य रूप से ऑब्जेक्ट को हटाने और मेमोरी को लीक करना भूल सकता है।
कच्चे पॉइंटर्स के साथ, प्रोग्रामर को ऑब्जेक्ट को स्पष्ट रूप से तबाह करना पड़ता है जब वह उपयोगी नहीं होता है।
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?
तुलना द्वारा एक स्मार्ट पॉइंटर एक नीति को परिभाषित करता है जब ऑब्जेक्ट नष्ट हो जाता है। आपको अभी भी ऑब्जेक्ट बनाना है, लेकिन अब आपको इसे नष्ट करने के बारे में चिंता करने की ज़रूरत नहीं है।
SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.
// Destruction of the object happens, depending
// on the policy the smart pointer class uses.
// Destruction would happen even if DoSomething()
// raises an exception
उपयोग में सबसे सरल नीति में स्मार्ट पॉइंटर रैपर ऑब्जेक्ट का दायरा शामिल होता है, जैसे कि इसके द्वारा कार्यान्वित boost::scoped_ptr
या std::unique_ptr
।
void f()
{
{
std::unique_ptr<MyObject> ptr(new MyObject());
ptr->DoSomethingUseful();
} // ptr goes out of scope --
// the MyObject is automatically destroyed.
// ptr->Oops(); // Compile error: "ptr" not defined
// since it is no longer in scope.
}
ध्यान दें कि std::unique_ptr
उदाहरणों की प्रतिलिपि नहीं बनाई जा सकती है। यह पॉइंटर को कई बार (गलत तरीके से) डिलीट होने से बचाता है। हालाँकि, आप अपने द्वारा कॉल किए जाने वाले अन्य कार्यों के लिए इसका संदर्भ दे सकते हैं।
std::unique_ptr
s तब उपयोगी होते हैं जब आप ऑब्जेक्ट के जीवनकाल को कोड के किसी विशेष ब्लॉक में बाँधना चाहते हैं, या यदि आप इसे किसी अन्य ऑब्जेक्ट के अंदर सदस्य डेटा के रूप में एम्बेड करते हैं, तो उस अन्य ऑब्जेक्ट का जीवनकाल। ऑब्जेक्ट तब तक मौजूद रहता है जब तक कि कोड के ब्लॉक से बाहर नहीं निकल जाता है, या जब तक कि संबंधित ऑब्जेक्ट स्वयं नष्ट नहीं हो जाता है।
अधिक जटिल स्मार्ट पॉइंटर नीति में पॉइंटर की गिनती के संदर्भ शामिल होते हैं। यह पॉइंटर को कॉपी करने की अनुमति देता है। जब ऑब्जेक्ट के लिए अंतिम "संदर्भ" नष्ट हो जाता है, तो ऑब्जेक्ट हटा दिया जाता है। इस नीति के द्वारा कार्यान्वित किया जाता है boost::shared_ptr
और std::shared_ptr
।
void f()
{
typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
// There is now one "reference" to the created object
p1 = p2; // Copy the pointer.
// There are now two references to the object.
} // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero.
// The object is deleted.
जब आपके ऑब्जेक्ट का जीवनकाल बहुत अधिक जटिल होता है, तो संदर्भ गिने पॉइंटर्स बहुत उपयोगी होते हैं, और कोड के किसी विशेष खंड या किसी अन्य ऑब्जेक्ट से सीधे बंधा नहीं होता है।
गिने हुए बिंदुओं को संदर्भित करने के लिए एक दोष है - झूलने वाले संदर्भ बनाने की संभावना:
// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
एक अन्य संभावना परिपत्र संदर्भ बना रही है:
struct Owner {
std::shared_ptr<Owner> other;
};
std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1
// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!
इस समस्या के आसपास काम करने के लिए, बूस्ट और सी ++ 11 ने ए weak_ptr
को कमजोर (बेशुमार) संदर्भ को परिभाषित करने के लिए परिभाषित किया है shared_ptr
।
std::auto_ptr<MyObject> p1 (new MyObject());
बजाय आप का मतलब है std::auto_ptr<MyObject> p1 (new Owner());
?
const std::auto_ptr
का उपयोग करना सुरक्षित है, यदि आप C ++ 03 के साथ फंस गए हैं। जब तक मुझे C ++ 11 तक पहुंच नहीं मिली, मैंने इसे pimpl पैटर्न के लिए बहुत उपयोग किया।
यहां आधुनिक C ++ (C ++ 11 और बाद के दिनों) के इन दिनों के लिए एक सरल उत्तर दिया गया है:
std::unique_ptr
जब आप एक ही ऑब्जेक्ट पर कई संदर्भ रखने का इरादा नहीं करते हैं तो उपयोग करें । उदाहरण के लिए, इसे एक पॉइंटर के लिए मेमोरी में उपयोग करें जो कुछ दायरे में प्रवेश करने पर आवंटित हो जाता है और दायरे से बाहर निकलने पर डी-आवंटित किया जाता है।std::shared_ptr
जब आप अपनी वस्तु को कई स्थानों से संदर्भित करना चाहते हैं, तब उपयोग करें - और यह नहीं चाहते कि आपकी वस्तु को तब तक आबंटित किया जाए जब तक कि ये सभी संदर्भ स्वयं नहीं हो जाते।std::weak_ptr
जब आप अपनी वस्तु को कई स्थानों से संदर्भित करना चाहते हैं, तो उपयोग करें - उन संदर्भों के लिए जिनके लिए इसे अनदेखा करना और डील-डौल करना ठीक है (इसलिए वे ध्यान दें कि जब आप किसी वस्तु को हटाने की कोशिश करते हैं तो वस्तु चली गई)boost::
स्मार्ट पॉइंटर का उपयोग न करें या std::auto_ptr
विशेष मामलों को छोड़कर जो आप पढ़ सकते हैं यदि आप अवश्य करें।T*
को std::unique_ptr<T>
क्या std::weak_ptr<T>
करना हैstd::shared_ptr<T>
स्मार्ट पॉइंटर कुछ अतिरिक्त कार्यक्षमता के साथ एक पॉइंटर-प्रकार का प्रकार है, जैसे स्वचालित मेमोरी डीलक्लेशन, संदर्भ गिनती आदि।
छोटा इंट्रो पेज स्मार्ट पॉइंटर्स पर उपलब्ध है - क्या, क्यों, कौन सा? ।
सरल स्मार्ट-पॉइंटर प्रकारों में से एक है std::auto_ptr
(C ++ मानक का अध्याय 20.4.5), जो जब स्कोप से बाहर होता है तो मेमोरी को स्वचालित रूप से डीलकोलेट करने की अनुमति देता है और अपवादों को फेंकने पर यह साधारण पॉइंटर उपयोग से अधिक मजबूत होता है, हालांकि कम लचीला।
एक और सुविधाजनक प्रकार है, boost::shared_ptr
जो संदर्भ की गिनती को लागू करता है और जब ऑब्जेक्ट का कोई संदर्भ नहीं रहता है तो स्वचालित रूप से मेमोरी को हटा देता है। यह मेमोरी लीक से बचने में मदद करता है और RAII को लागू करने के लिए उपयोग करना आसान है ।
डेविड वन्देवोर्डे, निकोलई एम। जोसुटिस , अध्याय 20 अध्याय द्वारा पुस्तक "सी ++ टेम्प्लेट्स: द कम्प्लीट गाइड" में विषय को गहराई से कवर किया गया है । स्मार्ट पॉइंटर्स कुछ विषयों को शामिल किया गया:
std::auto_ptr
को हटा दिया जाता है और अत्यधिक हतोत्साहित किया जाता है क्योंकि आप गलती से स्वामित्व स्थानांतरित कर सकते हैं। : - सी ++ 11 बूस्ट, उपयोग की जरूरत को हटा std::unique_ptr
, std::shared_ptr
औरstd::weak_ptr
क्रिस, सर्गदेव और लिलीओड द्वारा प्रदान की गई परिभाषाएं सही हैं। मैं एक सरल परिभाषा को पसंद करता हूं, बस अपने जीवन को सरल रखने के लिए: एक स्मार्ट पॉइंटर बस एक ऐसा वर्ग है जो ओवररेट ->
और *
ऑपरेटरों को अधिभारित करता है । जिसका अर्थ है कि आपकी वस्तु शब्दार्थ सूचक की तरह दिखती है, लेकिन आप इसे ठंडी चीजें कर सकते हैं, जिसमें संदर्भ गिनती, स्वचालित विनाश आदि शामिल हैं
shared_ptr
और auto_ptr
ज्यादातर मामलों में पर्याप्त हैं, लेकिन छोटे आइडियोसिंक्राइसिस के अपने स्वयं के सेट के साथ आते हैं।
एक स्मार्ट पॉइंटर एक रेगुलर (टाइप किया हुआ) पॉइंटर की तरह होता है, जैसे "चार *", सिवाय इसके कि जब पॉइंटर खुद ही स्कोप से बाहर चला जाता है तो यह किस पॉइंट को डिलीट कर देता है। आप इसका उपयोग कर सकते हैं जैसे कि आप "->" का उपयोग करके एक नियमित पॉइंटर करेंगे, लेकिन यदि आपको डेटा के लिए वास्तविक पॉइंटर की आवश्यकता नहीं है। उसके लिए, आप "& * ptr" का उपयोग कर सकते हैं।
यह इसके लिए उपयोगी है:
जिन वस्तुओं को नए के साथ आवंटित किया जाना चाहिए, लेकिन आप उस स्टैक पर कुछ के रूप में एक ही जीवनकाल करना चाहेंगे। यदि ऑब्जेक्ट एक स्मार्ट पॉइंटर को सौंपा गया है, तो प्रोग्राम को उस फ़ंक्शन / ब्लॉक से बाहर निकालने पर उन्हें हटा दिया जाएगा।
कक्षाओं के डेटा सदस्य, ताकि जब ऑब्जेक्ट को हटा दिया जाए तो सभी स्वामित्व डेटा नष्ट कर दिया जाए, बिना विध्वंसक में कोई विशेष कोड (आपको यह सुनिश्चित करने की आवश्यकता होगी कि विध्वंसक आभासी है, जो लगभग हमेशा एक अच्छी बात है) ।
जब आप एक स्मार्ट पॉइंटर का उपयोग नहीं करना चाहेंगे:
यह सभी देखें:
अधिकांश प्रकार के स्मार्ट पॉइंटर्स आपके लिए पॉइंटर-टू ऑब्जेक्ट का निपटान करते हैं। यह बहुत आसान है क्योंकि आपको मैन्युअल रूप से अब और वस्तुओं के निपटान के बारे में सोचने की ज़रूरत नहीं है।
सबसे अधिक इस्तेमाल किया जाने वाला स्मार्ट पॉइंटर्स हैं std::tr1::shared_ptr
(या boost::shared_ptr
), और, कम सामान्यतः std::auto_ptr
। मैं नियमित रूप से उपयोग की सलाह देता हूं shared_ptr
।
shared_ptr
बहुत बहुमुखी है और कई प्रकार के निपटान परिदृश्यों से संबंधित है, जिनमें ऐसे मामले शामिल हैं जिनमें वस्तुओं को "डीएलएल सीमाओं के पार जाना" चाहिए (यदि libc
आपके कोड और डीएलएल के बीच अलग-अलग एस का उपयोग किया जाता है तो सामान्य दुःस्वप्न मामला )।
एक स्मार्ट पॉइंटर एक ऐसी वस्तु है जो एक पॉइंटर की तरह काम करता है, लेकिन इसके अतिरिक्त निर्माण, विनाश, प्रतिलिपि बनाने, हिलाने और डिफरेंसिंग पर नियंत्रण प्रदान करता है।
कोई अपने स्मार्ट पॉइंटर को लागू कर सकता है, लेकिन कई लाइब्रेरी अलग-अलग फायदे और कमियों के साथ स्मार्ट पॉइंटर कार्यान्वयन भी प्रदान करते हैं।
उदाहरण के लिए, बूस्ट निम्नलिखित स्मार्ट सूचक कार्यान्वयन प्रदान करता है:
shared_ptr<T>
यह T
निर्धारित करने के लिए एक संदर्भ गिनती का उपयोग करने के लिए एक संकेतक है जब ऑब्जेक्ट की अब आवश्यकता नहीं है।scoped_ptr<T>
जब यह कार्यक्षेत्र से बाहर चला जाता है तो एक सूचक स्वचालित रूप से हटा दिया जाता है। कोई असाइनमेंट संभव नहीं है।intrusive_ptr<T>
एक और संदर्भ गिनती सूचक है। यह तुलना में बेहतर प्रदर्शन प्रदान करता है shared_ptr
, लेकिन T
इसके लिए अपने स्वयं के संदर्भ गिनती तंत्र प्रदान करने के प्रकार की आवश्यकता होती है।weak_ptr<T>
एक कमजोर सूचक है, जो shared_ptr
परिपत्र संदर्भों से बचने के लिए काम करता है ।shared_array<T>
की तरह है shared_ptr
, लेकिन सरणियों के लिए T
।scoped_array<T>
की तरह है scoped_ptr
, लेकिन सरणियों के लिए T
।ये प्रत्येक के केवल एक रैखिक विवरण हैं और आवश्यकता के अनुसार उपयोग किए जा सकते हैं, आगे के विवरण और उदाहरणों के लिए बूस्ट के प्रलेखन को देख सकते हैं।
इसके अतिरिक्त, C ++ मानक पुस्तकालय तीन स्मार्ट पॉइंटर्स प्रदान करता है; साझा स्वामित्व के लिए std::unique_ptr
, अद्वितीय स्वामित्व के std::shared_ptr
लिए और std::weak_ptr
। std::auto_ptr
C ++ 03 में मौजूद है लेकिन अब पदावनत हो गया है।
scoped_ptr
स्थानीय रूप से घोषित क्यों नहीं है const unique_ptr
- जो कि दायरे से बाहर निकलने पर भी नष्ट हो जाता है।
इसी तरह के उत्तरों के लिए लिंक यहां दिया गया है: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
एक स्मार्ट पॉइंटर एक ऐसी वस्तु है जो सामान्य पॉइंटर की तरह काम करता है, दिखता है और महसूस करता है लेकिन अधिक कार्यक्षमता प्रदान करता है। C ++ में, स्मार्ट पॉइंटर्स को टेम्पलेट कक्षाओं के रूप में लागू किया जाता है जो एक पॉइंटर को एनकैप्सुलेट करता है और मानक पॉइंटर ऑपरेटरों को ओवरराइड करता है। वे नियमित संकेत पर कई फायदे हैं। उन्हें शून्य बिंदु या संकेत के रूप में आरंभ करने की गारंटी दी जाती है। एक अशक्त सूचक के माध्यम से अप्रत्यक्षता की जाँच की जाती है। कोई डिलीट कभी जरूरी नहीं है। जब अंतिम पॉइंटर उनके पास चला गया है तो ऑब्जेक्ट स्वचालित रूप से मुक्त हो जाते हैं। इन स्मार्ट पॉइंटर्स के साथ एक महत्वपूर्ण समस्या यह है कि नियमित पॉइंटर्स के विपरीत, वे इनहेरिटेंस का सम्मान नहीं करते हैं। स्मार्ट पॉइमर पॉलीमॉर्फिक कोड के लिए अनाकर्षक हैं। नीचे दिए गए स्मार्ट पॉइंटर्स के कार्यान्वयन के लिए एक उदाहरण है।
उदाहरण:
template <class X>
class smart_pointer
{
public:
smart_pointer(); // makes a null pointer
smart_pointer(const X& x) // makes pointer to copy of x
X& operator *( );
const X& operator*( ) const;
X* operator->() const;
smart_pointer(const smart_pointer <X> &);
const smart_pointer <X> & operator =(const smart_pointer<X>&);
~smart_pointer();
private:
//...
};
यह वर्ग एक स्मार्ट पॉइंटर को X के ऑब्जेक्ट पर लागू करता है। ऑब्जेक्ट ही हीप पर स्थित है। यहाँ इसका उपयोग कैसे किया जाता है:
smart_pointer <employee> p= employee("Harris",1333);
अन्य ओवरलोड ऑपरेटरों की तरह, पी एक नियमित सूचक की तरह व्यवहार करेगा,
cout<<*p;
p->raise_salary(0.5);
http://en.wikipedia.org/wiki/Smart_pointer
कंप्यूटर विज्ञान में, एक स्मार्ट पॉइंटर एक अमूर्त डेटा प्रकार है जो अतिरिक्त सुविधाओं को प्रदान करते समय एक पॉइंटर का अनुकरण करता है, जैसे कि स्वचालित कचरा संग्रह या सीमा जाँच। इन अतिरिक्त विशेषताओं का उद्देश्य दक्षता बनाए रखते हुए पॉइंटर्स के दुरुपयोग के कारण होने वाले कीड़ों को कम करना है। स्मार्ट पॉइंटर्स आमतौर पर उन वस्तुओं पर नज़र रखते हैं जो उन्हें स्मृति प्रबंधन के उद्देश्य से इंगित करती हैं। पॉइंटर्स का दुरुपयोग बग्स का एक प्रमुख स्रोत है: निरंतर आवंटन, डीलक्लोकेशन और रेफ़रिंग जो कि पॉइंटर्स का उपयोग करके लिखे गए प्रोग्राम द्वारा किया जाना चाहिए, यह बहुत संभावना है कि कुछ मेमोरी लीक होगा। स्मार्ट पॉइंटर्स रिसोर्स लीक को ऑटोमैटिक बनाकर मेमोरी लीक्स को रोकने की कोशिश करते हैं: जब किसी ऑब्जेक्ट को पॉइंटर (या पॉइंटर्स की सीरीज़ में आखिरी) नष्ट हो जाता है,
बता दें कि T इस ट्यूटोरियल में C ++ में एक क्लास है, इसे 3 प्रकारों में विभाजित किया जा सकता है:
1) कच्चे संकेत :
T a;
T * _ptr = &a;
वे एक मेमोरी एड्रेस को मेमोरी में किसी लोकेशन पर रखते हैं। सावधानी बरतें, क्योंकि ट्रैक को बनाए रखने के लिए कार्यक्रम कठिन हो जाते हैं।
कास्ट डेटा या पते के साथ संकेत {आगे पीछे पढ़ें}
T a ;
const T * ptr1 = &a ;
T const * ptr1 = &a ;
एक डेटा टाइप T की ओर इशारा करता है जो एक कास्ट है। मतलब आप पॉइंटर का उपयोग करके डेटा प्रकार नहीं बदल सकते। यानी *ptr1 = 19
; काम नहीं करेगा। लेकिन आप पॉइंटर को मूव कर सकते हैं। यानी ptr1++ , ptr1--
; आदि काम करेंगे। पीछे की ओर पढ़ें: T टाइप करने के लिए पॉइंटर जो कांस्टेबल है
T * const ptr2 ;
डेटा टाइप T के लिए एक कास्ट पॉइंटर। मतलब आप पॉइंटर को हिला नहीं सकते लेकिन आप पॉइंटर द्वारा बताए गए मान को बदल सकते हैं। यानी *ptr2 = 19
काम करेगा लेकिन ptr2++ ; ptr2--
आदि नहीं चलेगा। पीछे की ओर पढ़ें: एक प्रकार टी के लिए कास्ट पॉइंटर
const T * const ptr3 ;
एक कास्ट पॉइंटर को एक कास्ट डेटा टाइप T। मतलब आप न तो पॉइंटर को हिला सकते हैं और न ही आप प्वाइंटर को डेटा टाइप पॉइंटर बदल सकते हैं। अर्थात । ptr3-- ; ptr3++ ; *ptr3 = 19;
काम नहीं करेगा
3) स्मार्ट पॉइंटर्स : { #include <memory>
}
साझा सूचक :
T a ;
//shared_ptr<T> shptr(new T) ; not recommended but works
shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe
std::cout << shptr.use_count() ; // 1 // gives the number of "
things " pointing to it.
T * temp = shptr.get(); // gives a pointer to object
// shared_pointer used like a regular pointer to call member functions
shptr->memFn();
(*shptr).memFn();
//
shptr.reset() ; // frees the object pointed to be the ptr
shptr = nullptr ; // frees the object
shptr = make_shared<T>() ; // frees the original object and points to new object
पॉइंटर द्वारा बताई गई वस्तु को कितनी "चीजों" को इंगित करने के लिए संदर्भ गिनती का उपयोग करके कार्यान्वित किया गया। जब यह संख्या 0 पर जाती है, तो ऑब्जेक्ट स्वचालित रूप से हटा दिया जाता है, अर्थात ऑब्जेक्ट को हटा दिया जाता है जब ऑब्जेक्ट के लिए सभी शेयर_पार्ट इंगित करते हैं, तो यह गुंजाइश से बाहर हो जाता है। यह उन वस्तुओं को हटाने के सिरदर्द से छुटकारा दिलाता है जिन्हें आपने नए का उपयोग करके आवंटित किया है।
कमजोर सूचक: साझा सूचक का उपयोग करते समय उत्पन्न होने वाले चक्रीय संदर्भ से निपटने में मदद करता है। यदि आपके पास दो साझा बिंदुओं द्वारा इंगित दो ऑब्जेक्ट हैं और एक आंतरिक साझा सूचक है जो एक दूसरे को साझा किए गए सूचक की ओर इशारा करता है तो एक चक्रीय संदर्भ होगा और ऑब्जेक्ट नहीं होगा साझा किए गए बिंदुओं के दायरे से बाहर जाने पर हटा दिया जाए। इसे हल करने के लिए, आंतरिक सदस्य को एक साझा_पत्र से कमजोर_प्रति में बदलें। नोट: एक कमजोर पॉइंटर उपयोग लॉक () द्वारा इंगित तत्व तक पहुंचने के लिए, यह एक कमजोर_प्रति देता है।
T a ;
shared_ptr<T> shr = make_shared<T>() ;
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr
wk.lock()->memFn() ; // use lock to get a shared_ptr
// ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access
देखें: कब है std :: weak_ptr उपयोगी?
अद्वितीय सूचक: विशेष स्वामित्व के साथ हल्के वजन वाले स्मार्ट पॉइंटर। जब पॉइंटर्स के बीच ऑब्जेक्ट्स को साझा किए बिना पॉइंटर पॉइंट्स को यूनीक ऑब्जेक्ट्स के लिए उपयोग करें।
unique_ptr<T> uptr(new T);
uptr->memFn();
//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr
अद्वितीय ptr द्वारा बताई गई वस्तु को बदलने के लिए, चाल शब्दार्थ का उपयोग करें
unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1);
// object pointed by uptr2 is deleted and
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null
संदर्भ: वे मूल रूप से कॉन्स्टेबल के रूप में हो सकते हैं, अर्थात एक पॉइंटर जो कि कास्ट है और बेहतर सिंटैक्स के साथ नहीं ले जाया जा सकता है।
देखें: C ++ में पॉइंटर वेरिएबल और रेफरेंस वेरिएबल के बीच क्या अंतर हैं?
r-value reference : reference to a temporary object
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified
संदर्भ: https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ इस प्रश्न को इंगित करने के लिए आंद्रे का धन्यवाद।
एक स्मार्ट पॉइंटर एक क्लास है, एक सामान्य पॉइंटर का आवरण है। सामान्य बिंदुओं के विपरीत, स्मार्ट पॉइंट का जीवन चक्र एक संदर्भ गणना (स्मार्ट पॉइंटर ऑब्जेक्ट को कितनी बार असाइन किया गया है) पर आधारित है। इसलिए जब भी एक स्मार्ट पॉइंटर दूसरे को सौंपा जाता है, तो आंतरिक संदर्भ गणना प्लस प्लस। और जब भी वस्तु दायरे से बाहर जाती है, तो संदर्भ शून्य से नीचे की गणना करता है।
स्वचालित पॉइंटर, हालांकि समान दिखता है, स्मार्ट पॉइंटर से पूरी तरह से अलग है। यह एक सुविधाजनक वर्ग है जो संसाधन से निपटता है जब भी कोई स्वचालित पॉइंटर ऑब्जेक्ट चर दायरे से बाहर जाता है। कुछ हद तक, यह एक पॉइंटर बनाता है (गतिशील रूप से आवंटित मेमोरी के लिए) स्टैक चर के समान काम करता है (संकलित समय में सांख्यिकीय रूप से आवंटित)।
स्मार्ट पॉइंटर्स वे हैं जहाँ आपको मेमोरी डी-एलोकेशन, रिसोर्स शेयरिंग और ट्रांसफर के बारे में चिंता करने की ज़रूरत नहीं है।
आप इन पॉइंटर का उपयोग ठीक उसी तरह से कर सकते हैं जिस तरह जावा में कोई आवंटन कार्य करता है। जावा गारबेज कलेक्टर में चाल करता है, जबकि स्मार्ट पॉइंटर्स में चाल विध्वंसक द्वारा किया जाता है।
मौजूदा उत्तर अच्छे हैं, लेकिन उस समस्या को कवर न करें जब कोई स्मार्ट पॉइंटर आपके द्वारा हल करने की कोशिश की जा रही समस्या का पूर्ण (पूर्ण) उत्तर न हो।
स्मार्ट पॉइंटर का उपयोग करके अन्य चीजों में (अच्छी तरह से समझाया गया) एक संभव समाधान है कि हम एक एब्सट्रैक्ट क्लास को फ़ंक्शन प्रकार के रूप में कैसे उपयोग करते हैं? जिसे इस प्रश्न के डुप्लिकेट के रूप में चिह्नित किया गया है। हालाँकि, यह पूछने का पहला प्रश्न कि क्या C ++ में रिटर्न टाइप के रूप में एक अमूर्त (या वास्तव में, कोई) आधार वर्ग निर्दिष्ट करने का प्रलोभन दिया गया है, "आप वास्तव में क्या मतलब है?"। बढ़ावा देने वाले पॉइंटर कंटेनर लाइब्रेरी के दस्तावेज़ीकरण में C ++ (और यह अन्य भाषाओं के लिए कैसे अलग है) में मुहावरेदार वस्तु उन्मुख प्रोग्रामिंग की एक अच्छी चर्चा (आगे के संदर्भों के साथ) है। सारांश में, C ++ में आपको स्वामित्व के बारे में सोचना होगा। कौन से स्मार्ट पॉइंटर्स आपकी मदद करते हैं, लेकिन एकमात्र समाधान नहीं है, या हमेशा एक पूर्ण समाधान (वे आपको बहुरूपिक प्रतिलिपि नहीं देते हैं) और हमेशा एक समाधान नहीं है जिसे आप अपने इंटरफ़ेस में उजागर करना चाहते हैं (और फ़ंक्शन रिटर्न एक भयानक लगता है एक अंतरफलक की तरह)। उदाहरण के लिए, किसी संदर्भ को लौटाना पर्याप्त हो सकता है। लेकिन इन मामलों में (स्मार्ट सूचक, सूचक कंटेनर या बस एक संदर्भ लौटने) के सभी में आप एक से वापसी को बदल दिया है मूल्य के कुछ फार्म के लिए संदर्भ । यदि आपको वास्तव में प्रतिलिपि की आवश्यकता है तो आपको अधिक बायलरप्लेट "मुहावरा" जोड़ने की आवश्यकता हो सकती है या मुहावरेदार से परे जा सकते हैं (या अन्यथा) सी ++ में ओओपी अधिक एडोब पॉली या Boost.TypeEypeureure जैसे पुस्तकालयों का उपयोग करते हुए अधिक सामान्य बहुरूपता के लिए।।