2011-09-14 7 views
6

मैं निम्नलिखित कोड कोशिश कर रहा हूँ:क्या vector.resize() विधि आकार बदलने पर डिफ़ॉल्ट तत्व कन्स्ट्रक्टर को कॉल करता है?

struct _Struct2 
{ 
    void *ptr; 
    double dval; 
}; 

struct _Struct 
{ 
    float fval; 
    int ival; 
    std::vector<_Struct2> data; 
}; 

std::vector<_Struct> vec; 


int main() 
{ 
    vec.resize(9); 
    for (int i = 0; i < vec.size(); i++) 
    { 
     _Struct &elem = vec[i]; 
     int  len = elem.data.size(); // elem.data is [0]() 
    } 
} 

आकार (9) प्रकार _Struct के 9 तत्वों का आवंटन करना चाहिए। और, वास्तव में यह काम करता है। लेकिन _Struct प्रकार के प्रत्येक तत्व को प्रारंभ नहीं किया गया है, विशेष रूप से डेटा तत्व, जो एक और std :: वेक्टर है। मैं इसे खाली std :: वेक्टर में प्रारंभ करना चाहता हूं। इसे मैन्युअल रूप से करना है? मैंने सोचा कि आकार बदलने() विधि प्रत्येक _Struct तत्व के डिफ़ॉल्ट कन्स्ट्रक्टर कहा होगा। Thx

Ps। यहां इस्तेमाल किए गए structs के नाम केवल पहली चीजें हैं जो मेरे दिमाग में आती हैं। यह सिर्फ एक उदाहरण है। मेरा विजुअल स्टूडियो मुझे बताता है कि elem.data डीबग व्यू में, [0]() पर मेल खाता है।

Ps। [0]() भूल जाओ।

+4

पहचानकर्ता जो अंडरस्कोर के साथ शुरू होते हैं उसके बाद अपरकेस अक्षर कार्यान्वयन के लिए आरक्षित होते हैं। –

+3

मैं कल्पना नहीं कर सकता कि 'len = elem.data.size() 'क्रैश नहीं हो रहा है अगर किसी भी तरह' डेटा' प्रारंभ नहीं किया गया था (जो यह निश्चित रूप से होना चाहिए)। वास्तव में 'डेटा' में क्या है और आप वहां क्या होने की उम्मीद करते हैं? – Jon

+1

वेक्टर में तत्व 'आकार' पर डिफ़ॉल्ट रूप से निर्मित होते हैं (एक पूर्णांक के लिए यह परिणाम 0 में) आपके कस्टम वर्ग के लिए, आपको अपना स्वयं का डिफ़ॉल्ट कन्स्ट्रक्टर परिभाषित करना चाहिए। –

उत्तर

16

नहीं, यह डिफ़ॉल्ट तत्व कन्स्ट्रक्टर को कॉल नहीं करता है। std::vector कभी भी आंतरिक कन्स्ट्रक्टर को आंतरिक रूप से कॉल नहीं करता है (यह सी ++ 11 में होता है, लेकिन विनिर्देश के पुराने संस्करणों में नहीं)।

vector::resize के लिए पूर्ण हस्ताक्षर के रूप में

void resize(size_type sz, T c = T()); 

यानी इस प्रकार लग रहा है इसमें दूसरा पैरामीटर है (डिफ़ॉल्ट तर्क मान के साथ)। उस दूसरे पैरामीटर को प्रति-निर्माता द्वारा नए तत्वों को आरंभ करने के लिए "स्रोत" ऑब्जेक्ट के रूप में उपयोग किया जाता है।

दूसरे शब्दों में, resize करने के लिए अपने कॉल वास्तव में

vec.resize(9, _Struct()); 

जिसका अर्थ है कि यह है आप जब आप vector::resize है कि "स्रोत" वस्तु की आपूर्ति की जो डिफ़ॉल्ट निर्माता कहा जाता है, भले ही आप नहीं था के बराबर है यह ध्यान नहीं दिया।

लेकिन प्रकार _Struct के प्रत्येक तत्व आरंभ नहीं किया है, विशेष रूप से डेटा तत्व है, जो एक और std :: वेक्टर है।

हुह? "शुरू नहीं हुआ"? मुझे नहीं पता कि इसका क्या मतलब है, इस पर विचार करते हुए कि आपके नमूना कोड में resize द्वारा बनाए गए हर नए तत्व को ऊपर वर्णित अनुसार पूरी तरह से प्रारंभ किया गया है: यह _Struct() तत्व से प्रतिलिपि बनाई गई है जिसे आपने दूसरे तर्क के रूप में resize पर निहित रूप से आपूर्ति की है। प्रत्येक _Struct::fval और _Struct::ival शून्य है, और प्रत्येक _Struct::data एक खाली वेक्टर है।

(मूल सी ++ 98 _Struct::fval और _Struct::ival, अप्रारंभीकृत रहेगा के बाद से पूर्व TC1 सी ++ 98 मूल्य प्रारंभ का समर्थन नहीं किया है। लेकिन _Struct::data भी मूल में एक खाली वेक्टर के लिए शुरू हो जाएगा सी ++ 98)।

मैं इसे खाली std :: वेक्टर में प्रारंभ करना चाहता हूं।

प्रत्येक _Struct::data वेक्टर पहले से ही एक खाली वेक्टर के रूप में शुरू किया गया है। आपने क्या विश्वास किया कि यह नहीं है?

पीएस नाम जो _ से शुरू होते हैं उसके बाद एक अपरकेस अक्षर कार्यान्वयन द्वारा आरक्षित होते हैं। आपको उनका उपयोग करने की अनुमति नहीं है।

+0

क्या सी ++ 11 'आकार बदलने' का एक इम्प्लेसिंग संस्करण जोड़ता है? –

+0

@ केरेक एसबी: मुझे वहां एक इम्प्लेसिंग संस्करण नहीं दिख रहा है, लेकिन सी ++ 11 दो कार्य में 'वेक्टर :: आकार बदलें' को विभाजित करता है: 1) बस आकार और 2) आकार और "स्रोत" ऑब्जेक्ट। पहला संस्करण अब मूल्य-प्रारंभिक रूप से आंतरिक रूप से निष्पादित करता है, जिसका अर्थ है कि मेरा उत्तर सी ++ 11 के लिए बिल्कुल सटीक नहीं है (भले ही अंतिम परिणाम समान है) – AnT

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