पॉइंटर्स या बस ऑब्जेक्ट्स?
आप सी ++ में किसी सरणी में संदर्भ नहीं डाल सकते हैं। आप संकेत की एक सरणी बना सकते हैं, लेकिन मैं अभी भी नहीं बल्कि संकेत की तुलना में एक कंटेनर और वास्तविक वस्तुओं की पसंद करते हैं क्योंकि:
- लीक करने के लिए कोई संभावना नहीं है, अपवाद सुरक्षा से निपटने के लिए आसान है।
- यह कम स्थान नहीं है - यदि आप पॉइंटर्स की एक सरणी संग्रहीत करते हैं तो आपको ऑब्जेक्ट के लिए स्मृति और पॉइंटर के लिए स्मृति की आवश्यकता होती है।
केवल बार मैं एक कंटेनर में संकेत डाल (या स्मार्ट संकेत बेहतर होगा) की वकालत चाहते हैं (या सरणी यदि आप चाहिए) है जब आपके वस्तु कंटेनरों के लिए construable और आबंटित एक आवश्यकता नकल नहीं है (, पॉइंटर्स हमेशा यह मिलते हैं) या आपको उन्हें पॉलिमॉर्फिक होने की आवश्यकता है। जैसे
#include <vector>
struct foo {
virtual void it() {}
};
struct bar : public foo {
int a;
virtual void it() {}
};
int main() {
std::vector<foo> v;
v.push_back(bar()); // not doing what you expected! (the temporary bar gets "made into" a foo before storing as a foo and your vector doesn't get a bar added)
std::vector<foo*> v2;
v2.push_back(new bar()); // Fine
}
आप इस सड़क boost pointer containers नीचे जाने के लिए ब्याज की हो सकता है क्योंकि वे कड़ी मेहनत के सभी करते हैं आप के लिए चाहते हैं।
सरणी या कंटेनरों से हटा रहा है।
NULL
असाइन करने से आपके कंटेनर/सरणी में कोई कम पॉइंटर्स नहीं बनता है, (यह delete
या तो संभाल नहीं करता है), आकार वही रहता है लेकिन अब पॉइंटर्स हैं जो आप कानूनी रूप से अपमान नहीं कर सकते हैं। यह आपके कोड के बाकी अधिक बयान करता है, तो अतिरिक्त के रूप में जटिल बना देता है और जैसी चीजों पर प्रतिबंध लगाता है:
// need to go out of our way to make sure there's no NULL here
std::for_each(v2.begin(),v2.end(), std::mem_fun(&foo::it));
मैं वास्तव में सामान्य रूप में संकेत के दृश्यों में NULL
रों अनुमति देने का विचार नापसंद है क्योंकि आप जल्दी से सभी दफन अंत सशर्त बयान के अनुक्रम में असली काम।
v2.erase(v2.begin());
पहले या v2.begin()+1
पल के लिए दूर करने के लिए: विकल्प है कि std::vector
एक erase
विधि है कि पुनरावर्तक तो आप लिख सकते हैं लेता है प्रदान करता है। समय जटिलता के कारण std::vector
पर हालांकि "एनएच तत्व मिटाएं" विधि आसान नहीं है - यदि आप बहुत सारे मिटा रहे हैं तो अन्य कंटेनर भी अधिक उपयुक्त हो सकते हैं।
एक सरणी आप के साथ मिटा अनुकरण कर सकते हैं के लिए:
#include <utility>
#include <iterator>
#include <algorithm>
#include <iostream>
int main() {
int arr[] = {1,2,3,4};
int len = sizeof(arr)/sizeof(*arr);
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// remove 2nd element, without preserving order:
std::swap(arr[1], arr[len-1]);
len -= 1;
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// and again, first element:
std::swap(arr[0], arr[len-1]);
len -= 1;
std::copy(arr, arr+len, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
आदेश संरक्षण एक भी स्वैप, जो अच्छी तरह से मिटा कि std::vector
चेहरे की जटिलता को दिखाता है के बजाय शफ़ल की एक श्रृंखला की आवश्यकता है। निश्चित रूप से ऐसा करने से आपने एक बहुत बड़ा पहिया फिर से शुरू किया है, एक मानक लाइब्रेरी कंटेनर की तुलना में बहुत कम उपयोगी और लचीला रूप से आपके लिए मुफ्त में होगा!
उपयोग और कंटेनर पर निर्भर करता है .. –
मुझे लगता है कि "संदर्भ" के साथ आप पॉइंटर्स का मतलब है। सी ++ में संदर्भ शून्य पर सेट नहीं किए जा सकते हैं, और आप वैसे भी संदर्भों की एक सरणी परिभाषित नहीं कर सकते हैं। – celtschk
कंटेनर एक सरणी है, और ऑब्जेक्ट को रनटाइम – user695652