2010-08-09 16 views
5
//Using g++ and ubuntu. 
#include <vector> 
using namespace std; 

एक वर्ग को परिभाषित करें:सी ++ कंस्ट्रक्टर्स के साथ वर्गों के वैक्टर

class foo(){ 
(...) 
foo(int arg1, double arg2); 
} 

कंस्ट्रक्टर:

foo::foo(int arg1, double arg2){ 
(...) //arrays whose length depend upon arg1 and arg2 
} 

मैं कुछ इस तरह करना चाहते हैं:

vector<foo> bar(10); //error: no matching function for call to 'foo::foo()' 
bar[0] = new foo(123, 4.56); 
(...) 

एक वैकल्पिक विधि (जो मुझे कम पसंद है) push_back का उपयोग करना है:

vector<foo> bar; //works 
bar.push_back(new foo(123, 4.56)); //throws similar error. 
//Omitting the "new" compiles but throws a "double free or corruption (fasttop)" on runtime. 

मैं वेक्टर के विभिन्न तत्वों का अलग-अलग निर्माण करना चाहता हूं, इसलिए मैं "दोहराव अनुक्रम कन्स्ट्रक्टर" का उपयोग नहीं करना चाहता हूं। क्या किया जाना चाहिए?

उत्तर

4

आप new का उपयोग क्यों कर रहे हैं जब कोई गतिशील स्मृति बनाने की आवश्यकता नहीं है? बेशक new का उपयोग विफल हो जाएगा, इसके परिणामस्वरूप foo* में push_backfoo स्वीकार करता है। (यही वह है जो आपके पास एक वेक्टर है।)

push_back के साथ क्या गलत है? यदि आप स्मृति को आगे आरक्षित करना चाहते हैं, तो reserve() का उपयोग करें; vector के निर्माता में एक संख्या प्रदान करने से दूसरे पैरामीटर की कई प्रतियां बनती हैं (जो कि foo() है, जो आपकी त्रुटियों को इसलिए काम नहीं करेगी), जो स्मृति को सुरक्षित रखने के समान नहीं है।

यदि चीजें सही तरीके से कर रही हैं (new) क्रैश, गलती आपके कोड में है और वेक्टर नहीं है। आप शायद एक उचित वर्ग संसाधनों का प्रबंधन नहीं लिखी है। * (The Big Three याद रखें, copy-and-swap idiom का उपयोग करें।)

* मैं यह कहना है क्योंकि आप कहते हैं कि "//arrays whose length depend upon arg1 and arg2 " है, जो मुझे लगता है मतलब है कि आप कहीं अपनी कक्षा में new[] है । बिग थ्री के बिना, आपका संसाधन प्रबंधन असफल हो जाएगा।

आपको संसाधनों का प्रबंधन नहीं करना चाहिए, कक्षाओं की एक ज़िम्मेदारी है। इसका मतलब है कि यह या तो एक गतिशील सरणी होनी चाहिए, या एक गतिशील सरणी का उपयोग करना चाहिए, लेकिन दोनों गतिशील सरणी का प्रबंधन और उपयोग नहीं करते हैं। इसलिए संसाधनों को अपनी कक्षा में कारक बनाएं, और फिर एक और वर्ग (आपका) बनाएं जो उनका उपयोग करता है। एक गतिशील सरणी std::vector है, इसलिए आप इसके साथ पहले से ही कर चुके हैं। कोई भी समय जब आपको गतिशील सरणी की आवश्यकता होती है, तो vector का उपयोग करें; ऐसा कोई कारण नहीं है।

+0

एक बहुत अच्छी जवाब के +1:

क्या आप शायद करना चाहिए निम्नलिखित है। यदि मैं कर सकता था, तो मैं यह नहीं कहने के लिए एक अतिरिक्त +1 देना चाहता हूं कि आपको हमेशा std :: वेक्टर का उपयोग करना चाहिए, लेकिन आपको हमेशा वेक्टर का उपयोग करना चाहिए। – Simon

0

std :: वेक्टर हमेशा डिफ़ॉल्ट कन्स्ट्रक्टर के आधार पर तत्व बनाते हैं जिन्हें आपने उपरोक्त स्निपेट में परिभाषित नहीं किया है।

पुश_बैक विधि को डबल फ्री इश्यू का सामना करना पड़ रहा है क्योंकि आपने कॉपी कन्स्ट्रक्टर को संभाल नहीं लिया है। क्योंकि std::vector निर्माता आप कॉल कर रहे

explicit vector (size_type n, const T& value= T(), const Allocator& = Allocator()); 

है आप देख सकते हैं

4
vector<foo> bar(10); //error: no matching function for call to 'foo::foo()' 

यह विफल हो रहा है, यह जो ऐसा नहीं करता foo के डिफ़ॉल्ट निर्माता के लिए 10 कॉल के साथ वेक्टर को भरने के लिए कोशिश कर रहा है मौजूद।

इसके अलावा, अपने सभी new विशेषता उदाहरण असफल हो जायेगी क्योंकि वेक्टर प्रकार foo, नहीं foo * की एक वस्तु की उम्मीद है। इसके अलावा, वेक्टर को साफ़ करने से पहले delete प्रत्येक सदस्य मैन्युअल रूप से delete तक vector<foo *> में बदलना विफल हो जाएगा। यदि आप वास्तव में गतिशील स्मृति आवंटन मार्ग जाना चाहते हैं तो vector< shared_ptr<foo> > बनाएं। shared_ptrBoost libraries में उपलब्ध है या यदि आपके कंपाइलर में TR1 लाइब्रेरी शामिल हैं तो यह हेडर में std::tr1 नामस्थान में मौजूद होगा या यदि आपके कंपाइलर में C++ 0x लाइब्रेरीज़ हैं तो यह std नेमस्पेस में ही उपलब्ध होगा।

vector<foo> bar; 
bar.reserve(10); 
bar.push_back(foo(1, 2)); 
... 
... 
bar.push_back(foo(10, 20)); //10 times 
+0

शायद उल्लेख करना चाहिए कि shared_ptr बूस्ट लाइब्रेरीज़ या सी ++ 0x –

+0

का हिस्सा है, यह अकेले काम नहीं करता है, लेकिन मुझे बड़ा होना चाहिए 3. –

+0

@ केविन: मुझे संदेह है कि आपको 'std :: vector' का उपयोग करना चाहिए आप नहीं करते उपयोग से कारक संसाधन करें, दोनों मत करो। – GManNickG

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