2011-12-28 17 views
15
/* bar.h */ 
class bar{ 
    /* standard stuff omitted */ 
    std::vector<my_obj*> foo; 
}; 

/* bar.cpp */ 
bar::bar(){ 
    // foo = new std::vector<my_obj*>(); <-- why don't I need this line?? 
    foo.push_back(new my_obj()); 
} 

यह बिना किसी काम के std :: vector का नया उदाहरण क्यों निर्दिष्ट करेगा?std :: वेक्टर प्रारंभ करने के लिए "नया" उपयोग करने की आवश्यकता क्यों नहीं है?

+0

उन्होंने क्या कहा। इसके अलावा, मैं 'foo.push_back (नया my_obj()) की अनुशंसा नहीं कर सकता;' क्योंकि आप वहां स्मृति को कहां मुक्त कर रहे हैं? –

उत्तर

33

क्योंकि सी ++ सी #/जावा नहीं है।

std::vector<my_obj*> foo; 

यह सी #/जावा में के रूप में एक वस्तु, नहीं एक संदर्भ की एक परिभाषा है। एक वस्तु एक प्रकार का एक जीवित उदाहरण है।

new std::vector<my_obj*>() 

यह अभिव्यक्ति एक सूचक देता है। यह std::vector<my_obj*>* देता है, जो समान प्रकार foo (* अंत में उन्हें अलग करता है) देता है। foo एक ऑब्जेक्ट है, std::vector<my_obj*>* किसी ऑब्जेक्ट के लिए पॉइंटर है।

ऑब्जेक्ट्स (पॉइंटर्स या संदर्भों के बजाए) में विशिष्ट जीवनकाल है। यदि आप किसी ऑब्जेक्ट को new के साथ पॉइंटर बनाते हैं, तो ऑब्जेक्ट का जीवनकाल तब तक इंगित होगा जब तक कि आप स्पष्ट रूप से delete पर कॉल न करें। यदि आप किसी ऑब्जेक्ट को किसी अन्य ऑब्जेक्ट के सदस्य के रूप में बनाते हैं, तो उस आंतरिक ऑब्जेक्ट का जीवनकाल (अधिक या कम) बाहरी ऑब्जेक्ट के जीवनकाल को दर्पण करेगा। यदि आप स्टैक पर एक ऑब्जेक्ट बनाते हैं (फ़ंक्शन स्कोप पर पैरामीटर या चर), तो यह जीवनकाल उस चर नाम का वर्तमान दायरा है।

6

क्योंकि bar में std::vector है, std::vector * नहीं।

यह वास्तव में कुछ इस तरह के अलग नहीं है:

class bar 
{ 
    int foo; // No need to create a "new int" 
}; 
1

std :: इस पुस्तकालय में वेक्टर एक सूचक

0

std::vector<my_obj *> foostd::vector<my_obj *> *foo से अलग है नहीं है। दूसरे मामले में आपको पहली बार उपयोग करने के लिए नए उपयोग करने की आवश्यकता होगी।

2

क्योंकि std::vector है कि आप के लिए :) खुद std::vector के लिए सूचक नहीं है, तो आप बस ऊपर प्रकार std::vector, जो आंतरिक रूप से आप के लिए स्मृति आवंटित की एक वस्तु स्थापित कर रहे है।

0

आप के बाद से foo एक vector एक vector (अर्थात std::vector<my_obj*> *foo) के लिए सूचक है, नहीं foo पर new उपयोग करने की आवश्यकता नहीं है।

यदि आप जावा या सी # से आ रहे हैं, तो आप पॉइंटर्स के वेक्टर के बजाय std::vector<my_obj> (ऑब्जेक्ट्स का एक वेक्टर) का उपयोग करने पर विचार करना चाह सकते हैं। यह वास्तव में निर्भर करता है कि आप क्या करना चाहते हैं।

3

क्योंकि foo एक ऑब्जेक्ट पॉइंटर नहीं है।

new std::vector<my_obj*>(); // returns std::vector<my_obj*> * 

पुनश्च:

std::vector<my_obj*> // This is an object 
std::vector<my_obj*> * // This is a pointer to an object 
        ^^^ // Notice the extra star. 

न्यू एक सूचक rerturns। आप वेक्टर में ऑब्जेक्ट्स पॉइंटर्स नहीं हो सकते हैं।

std::vector<my_obj> foo; 
... 
foo.push_back(my_obj()); 

नहीं तो आप मैन्युअल रूप से (जब से युक्त वस्तु नष्ट हो जाता है) वेक्टर में सभी वस्तुओं को नष्ट करने के लिए जब यह दायरे से बाहर चला जाता है की आवश्यकता होगी। यानी यदि आप अपने वेक्टर में पॉइंटर्स रखना चाहते हैं तो आपको निम्न में से एक करना चाहिए:

// 1. Manually delete all the elements in the vector when the object is destroyed. 
~bar::bar() 
{ 
    for(std::vector<my_obj*>::iterator loop = foo.begin(); loop != foo.end(); ++loop) 
    { 
     delete (*loop); 
    } 
} 

// 2. Use a smart pointer: 
std::vector<std::shared_ptr<my_obj> > foo; 

// 3. Use a smart container for pointers 
boost::ptr_vector<my_obj> foo 
संबंधित मुद्दे