मैं हर जगह संदर्भों का उपयोग करना पसंद करूंगा लेकिन जिस क्षण आप एक एसटीएल कंटेनर का उपयोग करते हैं, आपको पॉइंटर्स का उपयोग करना होगा जबतक कि आप वास्तव में जटिल प्रकारों को मूल्य से पास नहीं करना चाहते हैं।
बस स्पष्ट होने के लिए: एसटीएल कंटेनरों को कुछ अर्थशास्त्र ("मूल्य अर्थशास्त्र") का समर्थन करने के लिए डिज़ाइन किया गया था, जैसे "कंटेनर में आइटम की प्रतिलिपि बनाई जा सकती है।" चूंकि संदर्भ पुनर्निर्मित नहीं हैं, इसलिए वे मूल्य semantics का समर्थन नहीं करते हैं (यानी, std::vector<int&>
या std::list<double&>
बनाने का प्रयास करें)। आप सही हैं कि आप एसटीएल कंटेनर में संदर्भ नहीं डाल सकते हैं।
आम तौर पर, यदि आप सादे वस्तुओं के बजाय संदर्भों का उपयोग कर रहे हैं तो आप या तो बेस क्लास का उपयोग कर रहे हैं और स्लाइसिंग से बचने के लिए चाहते हैं, या आप प्रतिलिपि से बचने की कोशिश कर रहे हैं। और, हां, इसका मतलब यह है कि यदि आप आइटम को एसटीएल कंटेनर में स्टोर करना चाहते हैं, तो आपको स्लाइसिंग और/या प्रतिलिपि से बचने के लिए पॉइंटर्स का उपयोग करने की आवश्यकता होगी।
#include <iostream>
#include <vector>
// note signature, inside this function, i is an int&
// normally I would pass a const reference, but you can't add
// a "const* int" to a "std::vector<int*>"
void add_to_vector(std::vector<int*>& v, int& i)
{
v.push_back(&i);
}
int main()
{
int x = 5;
std::vector<int*> pointers_to_ints;
// x is passed by reference
// NOTE: this line could have simply been "pointers_to_ints.push_back(&x)"
// I simply wanted to demonstrate (in the body of add_to_vector) that
// taking the address of a reference returns the address of the object the
// reference refers to.
add_to_vector(pointers_to_ints, x);
// get the pointer to x out of the container
int* pointer_to_x = pointers_to_ints[0];
// dereference the pointer and initialize a reference with it
int& ref_to_x = *pointer_to_x;
// use the reference to change the original value (in this case, to change x)
ref_to_x = 42;
// show that x changed
std::cout << x << '\n';
}
ओह, और आप अगर वस्तुओं गतिशील बनाए गए थे या नहीं पता नहीं है:
और, हाँ, निम्नलिखित कानूनी (हालांकि इस मामले में, बहुत उपयोगी नहीं में) है।
यह महत्वपूर्ण नहीं है। उपर्युक्त नमूने में, x
स्टैक पर है और हम में x
पर एक पॉइंटर स्टोर करते हैं। निश्चित रूप से, pointers_to_vectors
आंतरिक रूप से गतिशील रूप से आवंटित सरणी का उपयोग करता है (और delete[]
वह सरणी जब vector
गुंजाइश से बाहर हो जाता है), लेकिन उस सरणी में पॉइंटर्स होते हैं, न कि चीजों को इंगित करते हैं। जब pointers_to_ints
गुंजाइश से बाहर हो जाता है, तो आंतरिक int*[]
delete[]
-ed है, लेकिन int*
एस delete
डी नहीं हैं।
यह वास्तव में, एसटीएल कंटेनरों के साथ पॉइंटर्स का उपयोग करता है, क्योंकि एसटीएल कंटेनर पॉइंट-ऑब्जेक्ट्स के जीवनकाल का प्रबंधन नहीं करेंगे। आप बूस्ट के सूचक कंटेनर लाइब्रेरी को देखना चाह सकते हैं। अन्यथा, आप या तो (1) स्मार्ट पॉइंटर्स के एसटीएल कंटेनरों का उपयोग करना चाहते हैं (जैसे boost:shared_ptr
जो एसटीएल कंटेनर के लिए कानूनी है) या (2) ऑब्जेक्ट्स के जीवनकाल को किसी अन्य तरीके से प्रबंधित करें। आप पहले से ही कर रहे हैं (2)।
मैं कहूंगा कि आप जो भी सूचक चाहते हैं उसे डिफरेंस कर सकते हैं लेकिन मुझे यकीन नहीं है कि ऐसा कोई कार्य क्या करेगा। –
@ जॉन: http://www.youtube.com/watch?v=sf-5RaFnh2U#t=2m14s :) –
@ जॉन: क्या आप हमें बता सकते हैं कि जिन वस्तुओं को आप पॉइंटर्स संग्रहीत कर रहे हैं वे गतिशील रूप से आवंटित किए गए हैं? मुझे लगता है कि यह मामला था, लेकिन एक पूर्ण आवश्यकता नहीं है। –