2013-11-01 4 views
5

मुझे कुछ प्रश्नोत्तरी "Is a string a vector? If yes, in what way? If no, why not?" दोनों में एक प्रश्न का सामना करना पड़ा है, दोनों में सामग्री के लिए यादृच्छिक पहुंच है। लेकिन स्ट्रिंग कुछ तरीकों जो भी dosn`t.It वेक्टर संदर्भ गिनती हो सकता है। तो यह स्पष्ट है कि स्ट्रिंग वास्तव में एक सदिश (typedef स्ट्रिंग वेक्टर) जो class string : public vector <char> में वहाँ जाना जाता हैं कार्यान्वयन नहीं है? यदि नहीं - तो इसे लागू करने का कारण क्या है?एसटीएल - एक स्ट्रिंग एक वेक्टर है?

+0

स्ट्रिंग में कुछ विधियां हैं जो वेक्टर नहीं हैं? इसके विपरीत यह सच है। –

+0

@MehdiTaxir - परीक्षा के लिए c_str() या डेटा() या find_first_of() आदि – Yakov

+2

नोट: सी ++ 11 संदर्भित गिनती स्ट्रिंग्स को स्पष्ट रूप से मना करता है –

उत्तर

6

पूरी तरह से दार्शनिक दृष्टिकोण से: हाँ, एक स्ट्रिंग वेक्टर के टाइप करें। यह एक संगत स्मृति ब्लॉक है जो वर्णों को संग्रहीत करता है (एक वेक्टर एक संगत स्मृति ब्लॉक है जो मनमाने ढंग से वस्तुओं की वस्तुओं को संग्रहीत करता है)। तो, इस परिप्रेक्ष्य से, एक स्ट्रिंग एक विशेष प्रकार का वेक्टर है।

डिजाइन और std::string और std::vector के कार्यान्वयन के संदर्भ में, वे एक ही इंटरफ़ेस तत्वों में से कुछ (जैसे सन्निहित स्मृति ब्लॉक, operator[]) का हिस्सा है, लेकिन नहींstd::vector (पक्ष टिप्पणी से निकाले जाते हैं std::string करता है: आप सार्वजनिक रूप से प्राप्त नहीं करना चाहिए मानक कंटेनरों से, क्योंकि वे कक्षाओं के लिए डिज़ाइन नहीं किए गए हैं - उदाहरण के लिए उनके पास आभासी विनाशक नहीं हैं), न ही वे एक दूसरे के लिए सीधे परिवर्तनीय हैं। यही कारण है, निम्नलिखित संकलन नहीं:

std::string s = "abc"; 
std::vector<char> v = s; // ERROR! 

हालांकि, बाद से वे दोनों इटरेटर समर्थन है, तो आप एक वेक्टर के लिए एक स्ट्रिंग परिवर्तित कर सकते हैं:

std::string s = "abc"; 
std::vector<char> v(s.begin(), s.end()); // note that the vector will NOT include the '\0' character 

std::string अब एक संदर्भ गिनती करना होगा (सी ++ 11 के रूप में) कॉपी-ऑन-राइट कार्यक्षमता के रूप में उपयोग किए गए कई कार्यान्वयन सी ++ 11 मानक द्वारा प्रतिबंधित थे।

एक स्मृति दृष्टिकोण से, std::string का एक उदाहरण दिखेगा बहुत समान एक std::vector<char> (जैसे वे दोनों अपने स्मृति स्थान, एक आकार, क्षमता के लिए सूचक होगा), लेकिन दो वर्गों की कार्यक्षमता के लिए है विभिन्न।

+0

"आपको मानक कंटेनरों से सार्वजनिक रूप से प्राप्त नहीं करना चाहिए क्योंकि उनके पास वर्चुअल विनाशक नहीं हैं"। हम्म, मुझे लगता है कि यह काफी हद तक सच है, लेकिन इसके बारे में चमक थोड़ा सा है। मैं बीच में कुछ पाठ डाल दूंगा: "आपको मानक कंटेनरों से सार्वजनिक रूप से प्राप्त नहीं करना चाहिए क्योंकि उन्हें बेस क्लास के रूप में उपयोग करने के लिए डिज़ाइन नहीं किया गया है। इसका एक संकेत यह है कि उनके पास आभासी विनाशक नहीं हैं।" यह एकमात्र कारण नहीं है, और पूरी तरह से एक कारण नहीं है। – BoBTFish

+0

@BoBTFish अच्छा बिंदु। मैं शब्द समायोजित कर दूंगा। –

+0

शब्दावली पर बस एक नाइट, लेकिन एक वेक्टर प्रकारों को स्टोर नहीं करता है, यह एक मनमाना प्रकार की वस्तुओं को स्टोर करता है। (अधिक या कम: वस्तुओं को कॉपी करने योग्य होना चाहिए, उदाहरण के लिए।) –

10

std::stringstd::vector (और अन्य मानक कंटेनर) के साथ आम तौर पर इसके इंटरफ़ेस का एक गैर-मामूली हिस्सा है, लेकिन यह एक अलग उद्देश्य के साथ, निश्चित रूप से एक अलग बात है।

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

वे दोनों रैंडम एक्सेस iterators का समर्थन है, तो मानक एल्गोरिदम के साथ इसी तरह तरीकों से किया जा सकता है। मुझे लगता है कि std::string एक दृश्य कंटेनर के रूप में वर्गीकृत नहीं किया जा सकता।

यह सीधे std::vector से इनहेरिट द्वारा std::string के सदस्य कार्यों को कार्यान्वित करने, क्योंकि यह तथ्य यह है कि यह भी एक NUL -terminator भंडारण है छुपाता संभव नहीं होगा। तो जब std::string::size रिटर्न 3, std::vector::size4 वापसी होगी, उदाहरण के लिए। end, और कुछ अन्य के लिए भी चला जाता है।

3

नहीं है, std::string (std::basic_string<char>), तो आप इसके बारे में अनुक्रम कंटेनर कि char शामिल के रूप में यह अन्य कंटेनरों के साथ कई कार्यों के शेयरों का एक प्रकार में सोच सकते हैं, लेकिन यह std::vector का उपयोग कर लागू नहीं किया है।

3

मुख्य कारण यह है कि सार्वजनिक विरासत का उपयोग करके इसे लागू नहीं किया जा सकता (या कम से कम निश्चित रूप से नहीं होना चाहिए) यह है कि string से vector तक अंतर्निहित रूपांतरण की अनुमति नहीं दी जानी चाहिए।

int f(std::vector<char> const &s); 

// ... 

std::string s; 
f(s); 

संकलन विफल करना चाहिए (कि एक string स्वीकार करता f के कुछ अन्य अधिभार अनुपस्थित): उदाहरण के लिए, अगर मैं की तरह कोड लिखने।

तुम सच में करना चाहता था, तो आप सकता (शायद) std::vector से का उपयोग कर std::string के एक वैध कार्यान्वयन निजी विरासत हालांकि करते हैं। यह संभवतः जितना संभव हो उतना कुशल नहीं हो सकता है, लेकिन कम से कम ऑफहैंड, मैं एक आवश्यकता के बारे में नहीं सोच सकता जो स्पष्ट रूप से उल्लंघन करेगा। दक्षता का नुकसान इस तथ्य से होगा कि std::vector को कुछ और सामान्य होने की आवश्यकता है - इसे अपवादों को फेंकने वाले प्रकारों पर तत्कालता का समर्थन करना चाहिए, जबकि std::string केवल अपवाद मुक्त प्रकारों पर तत्काल स्थापित करने के लिए डिज़ाइन किया गया है।

+0

सार्वजनिक विरासत का उपयोग करके इसे लागू नहीं किया जा सकता है एक अन्य कारण एक आभासी विनाशक (किसी भी std कंटेनर के लिए) की कमी है। –

+0

@ZacHowland अच्छा विचार यह है कि मुझे लगता है कि विरासत केवल एक कार्यान्वयन विस्तार होगा जिसके बारे में कोई उपयोगकर्ता नहीं जानता है, इसलिए वे कभी भी 'std :: vector * '' std :: string' पर संग्रहीत नहीं करेंगे, और निश्चित रूप से इसे हटाएं नहीं। – BoBTFish

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