2011-09-24 3 views
5

मैं बहुत की तरह एक शीर्षक में एक वेक्टर है,:ग्लोबल वेक्टर कॉल के बीच खुद को खाली कर रहा है?

extern std::vector<Foo> g_vector; 

जुड़े cpp फ़ाइल में मैं इस है:

std::vector<Foo> g_vector; 

मैं भी एक वर्ग Bar है, और इसे के निर्माता में जोड़ देगा g_vector करने के लिए कुछ सामान है, तो जैसे:

Bar::Bar(/* stuff */) 
{ 
    // do things 
    std::cout << g_vector.size() << std::endl; 
    g_vector.push_back(somefoo); 
    std::cout << g_vector.size() << std::endl; 
} 

अगर मैं एक समारोह के अंदर घोषित एक Bar, एक समझदार की तरह व्यक्ति, यह ठीक काम करता प्रतीत होता है। हालांकि, अगर मैं किसी फ़ंक्शन के बाहर Bar घोषित करना चाहता हूं, तो अजीब चीजें होती हैं। उदाहरण के लिए, मेरे पास Bar है MyFile1.cpp और MyFile2.cpp में घोषित किया गया है, और बार में मेरे कोउट स्टेटमेंट्स के कारण मैं Foo को वेक्टर में धक्का दे सकता हूं, लेकिन जब अगला Bar इसके कन्स्ट्रक्टर को चलाता है तो वेक्टर का आकार 0 है फिर। दूसरे शब्दों में, मेरा आउटपुट

0 
1 
0 
1 

क्या देता है? बस अतिरिक्त डबल होने के लिए, मैंने यह सुनिश्चित करने के लिए &g_vector प्रिंट करने का भी प्रयास किया है कि यह वास्तव में सही वेक्टर में push_back आईएनजी था, और सभी मिलान पते। इसके लायक होने के लिए, इससे कोई फर्क नहीं पड़ता कि इन चीजों को वेक्टर में किस क्रम में जाना है। मैं प्रारंभिक आदेश या कुछ भी नहीं चिंतित हूं।

+1

क्या आपके पास यह मानने का कोई कारण है कि आपका 'g_vector' आपके स्थिर' बार 'उदाहरण से पहले बनाया जाएगा? – Gabe

उत्तर

6

यह सुनिश्चित नहीं है कि वास्तव में समस्या क्या है, लेकिन मुझे लगता है कि निम्न पैटर्न इसे हल करने में मदद करेगा: वैश्विक चर के लिए एक एक्सेसर परिभाषित करें और इसे नीचे दिखाए गए स्थिर फ़ंक्शन वैरिएबल के रूप में आवंटित करें।

हेडर फाइल में:

std::vector<Foo> &getGlobalVector(); 

cpp फ़ाइल में:

std::vector<Foo> &getGlobalVector() 
{ 
    static std::vector<Foo> s_vector; 
    return s_vector; 
} 

यह पैटर्न आधुनिक सी ++ डिजाइन में आंद्रेई Alexandrescu के "सामान्य सिंगलटन" कार्यान्वयन से प्रेरित है।

जब भी मैं मौजूदा अनुप्रयोगों को बनाए रखने के दौरान मौजूदा ग्लोबल वैरिएबल पर गिरता हूं (या दुर्लभ अवसरों में मैंने वास्तव में खुद का उपयोग करने के लिए चुना है), तो इस पद्धति का उपयोग करके व्यवस्थित रूप से इस आदत का उपयोग किया है, और इससे किसी को समाप्त करने में मदद मिली हो सकती है कहा अनुप्रयोगों में हार्ड-टू-रीप्रोडस बग्स के जोड़े।

किसी भी दर पर, यह वास्तव में किसी भी बहु-प्रारंभिकरण या आदेश-प्रारंभ-प्रारंभिक समस्या से बचने में मदद करनी चाहिए।

6

वैश्विक मूल्यों के प्रारंभिकरण के आदेश को परिभाषित नहीं किया गया है।

static initialization fiasco के बारे में यहां पढ़ें।

जब आप किसी फ़ंक्शन में Bar घोषित करते हैं - g_vector पहले शुरू किया जाएगा, क्योंकि प्रोग्राम चलाने से पहले इसे आरंभ करने का वादा किया गया था। यदि Bar एक वैश्विक चर है - तो आपको एक समस्या है।

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