2013-11-23 19 views
6

मेरे सी ++ कोड में मेरे पास एक प्रकार का ऑब्जेक्ट टाइप आईडी प्रकार से सुसज्जित है। अब मैं ऑब्जेक्ट * प्रकार के पॉइंटर्स का वेक्टर बनाना चाहता हूं। सबसे पहले मैंनेपॉइंटर्स के सी ++ वेक्टर बनाना

vector<Object*> v; 

for(int id=0; id<n; id++) { 
    Object ob = Object(id); 
    v.push_back(&ob); 
} 

लेकिन यह असफल रहा क्योंकि यहां एक ही पता बस स्वयं को दो बार दोहराता है। अगर मैंने नया ऑपरेटर इस्तेमाल किया तो मुझे वह चाहिए जो मैं चाहता हूं लेकिन मैं गतिशील स्मृति आवंटन से बचना चाहता हूं। तब मैंने सोचा कि मुझे लूप से पहले एन अलग पॉइंटर्स घोषित करने की ज़रूरत है।

vector<Object*> v; 
Object ar[n]; 

for(int i=0; i<n; i++) { 
    ar[i] = Object(i); 
} 

for(int i=0; i<n; i++) { 
    v.push_back(ar+i); 
} 

वहाँ अभी भी एक स्मृति रिसाव पाने के लिए अगर मैं इसे इस तरह से करना संभावना है: यह करने के लिए सरल तरीके से एक सरणी तो मैं ऐसा किया घोषित करने के लिए है? एक सरणी घोषणा के माध्यम से भी मेरी राय में थोड़ा बेकार है। क्या पॉइंटर्स के वेक्टर बनाने के लिए कोई और तरीका है लेकिन मैन्युअल मेमोरी प्रबंधन से बचें?

संपादित करें: मैं केवल साधारण वस्तुओं के बजाय पॉइंटर्स क्यों चाहता हूं?

अच्छी तरह से मैंने मूल वास्तविक स्थिति को थोड़ा सा संशोधित किया क्योंकि मैंने सोचा था कि इस तरह से मैं सबसे सरल संभव रूप में प्रश्न का प्रतिनिधित्व कर सकता हूं। वैसे भी मुझे अभी भी लगता है कि बिना सवाल के सवाल पूछे जा सकते हैं कि मैं पॉइंटर्स का वेक्टर क्यों चाहता हूं।

वास्तव में मुझे लगता है मैं प्रकार Object की वस्तुओं के साथ सदस्य क्षेत्र vec भरना चाहते हैं

Class A { 
protected: 
    vector<Superobject*> vec; 
... 
}; 

Class B: public A {...}; 

Class Superobject { 
protected: 
    int id; 
... 
} 

Class Object: public Superobject {...} 

है व्युत्पन्न वर्ग B में। अगर सुपरक्लस पॉइंटर्स का उपयोग नहीं करता है तो मुझे ऑब्जेक्ट स्लाइसिंग में समस्या होगी। तो कक्षा B कन्स्ट्रक्टर में मैं vec को Object* के पॉइंटर्स के वेक्टर के रूप में प्रारंभ करना चाहता हूं।

EDIT2

हाँ, मुझे लगता है कि गतिशील आवंटन उचित विकल्प और विचार एक सरणी का उपयोग करना है एक बुरा विचार है। जब सरणी गुंजाइश से बाहर हो जाती है, तो चीजें गलत हो जाती हैं क्योंकि वेक्टर में पॉइंटर्स स्मृति स्थानों पर इंगित करते हैं जिनमें जरूरी वस्तुओं को शामिल नहीं किया जाता है।

वर्ग बी के लिए निर्माता में मैं

B(int n) { 
    vector<Object*> vec; 
    Object ar[n]; 

    for(int id=0; id<n; id++) { 
     ar[id] = Object(id); 
    } 

    for(int id=0; id<n; id++) { 
     v.push_back(ar+id); 
    } 
} 

इस वर्ग बी की वस्तुओं में बहुत अजीब व्यवहार की वजह से

+2

यदि आप गतिशील स्मृति आवंटन नहीं चाहते हैं तो आप पॉइंटर्स का उपयोग क्यों कर रहे हैं? आप ऑब्जेक्ट की सरणी के साथ भी काम कर सकते हैं। –

+1

आप पॉइंटर्स को पहली जगह क्यों स्टोर करना चाहते हैं? – Yuushi

+1

आपके साथ दूसरी विधि समस्या यह है कि यह कानूनी सी ++ नहीं है। 'ऑब्जेक्ट ar [n];' कानूनी नहीं है जब तक कि स्थिर न हो। इसके अलावा आपके संपादन के अनुसार आपके पास एक श्रेणी पदानुक्रम है लेकिन 'ऑब्जेक्ट आर [एन] के साथ; आपके पास ऑब्जेक्ट्स हैं, सुपरबोजेक्ट्स नहीं। बीटीडब्ल्यू आपकी पहली विधि भी इस कारण के लिए गलत है कि आप वस्तुओं के पते को संग्रहीत कर रहे हैं जो नष्ट हो गए हैं। मैं बस गतिशील स्मृति आवंटन का उपयोग करेंगे। – john

उत्तर

6

इस पाश में:

for(int id=0; id<n; id++) { 
    Object ob = Object(id); 
    v.push_back(&ob); 
} 

आप n बार पैदा कर रहे स्टैक पर उदाहरण वस्तु। प्रत्येक पुनरावृत्ति पर तत्व बनाया और हटा दिया जाता है। आप इसे आसानी से इस से बच सकते हैं:

for(int id=0; id<n; id++) { 
    Object* ob = new Object(id); 
    v.push_back(ob); 
} 

धन्यवाद कि प्रत्येक नया तत्व ढेर पर ढेर पर मौजूद नहीं है। ऐसे ही वर्ग वस्तु निर्माता कुछ में जोड़ने के लिए प्रयास करें:

std::cout<<"Object ctor()\n"; 

और नाशक में ही:

std::cout<<"Object dtor()\n"; 

आप 'नई' @ द्वारा लिखित कारण की कोशिश के साथ इन वस्तुओं का निर्माण करना चाहते हैं न ऊनस्टार

+0

+1 – Pat

3

कोई आपकी संस्करण में कोई स्मृति रिसाव है था। जब कार्यक्रम आपके दायरे को वेक्टर छोड़ देता है तो सरणी नष्ट हो जाती है। अपने दूसरे प्रश्न के लिए: वस्तुओं को सीधे वेक्टर में क्यों न स्टोर करें?

vector<Object> v; 

for(int i = 0; i < n; i++) 
{ 
    Object obj = Object(i); 
    v.push_back(obj); 
} 
5

आपका मेमोरी लीक के बारे में सवाल मुझे लगता है कि आप जीवन चक्र और इन वस्तुओं में से सफाई के बारे में चिंतित हैं बनाता है। मैंने मूल रूप से shared_ptr रैपर प्रस्तावित किए, लेकिन सी ++ 11 ने हमें unique_ptr दिया, और सी ++ 14 गायब make_unique में भरा।सभी के साथ तो हम ऐसा कर सकते हैं:

vector<unique_ptr<SuperObject>> v ; 

जो तुम सही अग्रेषण और variadic टेम्पलेट्स के wonderfulness के साथ जगह में बनाते हैं, तो

v.push_back(make_unique<Object>(...)) ; 

हाँ आप कुछ ढेर आवंटन साथ रहने के लिए है करने के लिए जा रहे हैं, लेकिन v दूर चला जाता है जब सब कुछ साफ हो जाएगा।

किसी ने बूस्ट लाइब्रेरी, ptr_container का प्रस्ताव दिया है, लेकिन इसके लिए न केवल आपके प्रोजेक्ट को बढ़ावा देना आवश्यक है, बल्कि भविष्य के पाठकों को शिक्षित करने की आवश्यकता है कि यह ptr_container क्या है और करता है।

+3

कृपया, जब तक आपको shared_ptr semantics की आवश्यकता न हो, ऐसा न करें। बस http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/ptr_container.html का उपयोग करें। त्रुटि को ध्यान में रखते हुए – KitsuneYMG

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