2013-12-17 7 views
9

जबकि कुछ विरासत कोड के साथ एक परियोजना में काम कर मैं इस समारोह पाया:शुरु कर रहा है std :: एसटीडी के वेक्टर :: स्ट्रिंग

std::vector<std::string> Object::getTypes(){ 
    static std::string types [] = {"type1","type2", "type3"}; 
    return std::vector<std::string> (types , types +2); 
} 

मैं शायद इस रूप में लिखा है |:

std::vector<std::string> Object::getTypes(){ 
    std::vector<std::string> types; 
    types.push_back("type1"); 
    types.push_back("type2"); 
    types.push_back("type3"); 
    return types; 
} 

है यह केवल एक स्टाइल पसंद है या क्या मुझे कुछ याद आ रही है? किसी भी तरह की सहायता का स्वागत किया जाएगा। क्षमा करें अगर यह बहुत बुनियादी है।

अद्यतन: असल में पाया विभिन्न वर्गों है कि एक ही विधि ओवरराइड, यह एक ही रास्ता या अन्य ऐसा यह और भी अस्पष्ट है। मैं उन्हें सब कुछ वही बना दूंगा लेकिन यदि कोई है तो बेहतर दृष्टिकोण पसंद करेंगे।


संपादित

कृपया ध्यान दें कि ऊपर विरासत कोड गलत है क्योंकि यह केवल पहले दो सरणी के तत्वों के साथ वेक्टर initializes। हालांकि, टिप्पणियों में इस त्रुटि पर चर्चा की गई है और इस प्रकार संरक्षित किया जाना चाहिए।

... 
    return std::vector<std::string> (types, types + 3); 
... 
+2

पहला अवतार सिद्धांत रूप में अधिक कुशल हो सकता है क्योंकि इसमें किसी भी स्मृति पुन: आवंटन शामिल नहीं है। कम फ़ंक्शन कॉल भी हैं। सी ++ में नोट 11 आप कह सकते हैं 'वापसी std :: वेक्टर {"टाइप 1", "टाइप 2", "टाइप 3"}; '। – juanchopanza

+2

@juanchopanza इसके अलावा, उस संस्करण में, कोड और डेटा का अलगाव अधिक स्पष्ट है, इसलिए यह वाक्य रचनात्मक रूप से क्लीनर है। –

+0

मेरी पिछली टिप्पणी में सुधार: सी ++ 11 में, आप इसे कम शब्दों में प्राप्त कर सकते हैं: 'वापसी {" टाइप 1 "," टाइप 2 "," टाइप 3 "};'। – juanchopanza

उत्तर

1

पहले उदाहरण में सरणी types स्थिर घोषित किया जाता है। इसका मतलब है कि यह स्मृति में एक बार मौजूद है। तो वापस आने के लिए तीन विकल्प हैं और वे स्थिर स्मृति में रहते हैं। फिर, जब आप वापस जाने के लिए वेक्टर बनाते हैं, आप शुरुआत से गुजर रहा है और iterators के रूप में सरणी के समाप्त होने से यह स्मृति है आवंटित करने के लिए एक शॉट में सक्षम हैं।

ऐसा करने से, आपके पास push_back पर लगातार कॉल नहीं हैं जिसका अर्थ है कि वेक्टर को स्मृति के आंतरिक ब्लॉक को पुन: आवंटित नहीं करना होगा।

इसके अलावा, जब वेक्टर वापसी कॉल के हिस्से के रूप का निर्माण किया है, पुराने compilers return value optimization करने का एक आसान समय होगा।

+0

आरवीओ सभी कोड के लिए समान रूप से लागू होता है। यहां तक ​​कि "पुराने" कंपाइलर्स के साथ (जिनमें से कई ने हाल ही में कुछ हालिया कंपाइलरों की तुलना में बेहतर किया है)। –

5

कोड आप पाया और अधिक कुशल है (क्योंकि types[] केवल एक बार आवंटित किया जाता है और push_back/पुनः आवंटन का कारण होगा सकते हैं):

सही प्रारंभ इस प्रकार के रूप में पढ़ा जाना चाहिए था। अंतर हालांकि सीमांत है, और जब तक आप एक (अपेक्षाकृत बड़ा) पाश में getTypes फोन यह बिल्कुल कोई फर्क नहीं करना चाहिए (और शायद यह ज्यादा बात यहाँ तक कि जब आप ऐसा करेंगे एक बड़ा पाश में इसे कहते नहीं होगा)।

जैसे, जब तक कि यह एक ठोस प्रदर्शन समस्या पैदा करता है, यह एक शैली पसंद है।

9

आप एक सी ++ 11 सक्षम संकलक और पुस्तकालय है, तो एक प्रारंभकर्ता सूची लौटने के लिए पर्याप्त होना चाहिए:

std::vector<std::string> Object::getTypes(){ 
    return {"type1","type2", "type3"}; 
} 
3

मूल रूप से यह एक शैली पसंद है। मैं शायद और अधिक की तरह

std::vector<std::string> Object::getTypes(){ 
    static std::string types [] = {"type1","type2", "type3"}; 
    return std::vector<std::string> (types, 
        types + (sizeof(types)/sizeof(std::string))); 
} 

आप अगली पंक्ति में गणना को अपडेट करने के लिए याद करने के लिए बिना, प्रकार में चीजों की संख्या में परिवर्तन की सुविधा देता है जो कुछ करना चाहते हैं।

+0

यह मुझे एक त्रुटि देता है अगर मैं ऐसा करने की कोशिश करता हूं, "std :: vector 'के प्रारंभ के लिए कोई मिलान करने वाला कन्स्ट्रक्टर नहीं है। शुरू में मैंने सोचा था कि मुझे ऐसा करना चाहिए जैसा कि आप कहते हैं, लेकिन यह संकलित नहीं करता है। –

+0

@AndresBucci आपको 'std :: vector (प्रकार, प्रकार + आकार (प्रकार)/आकार (std :: string) की आवश्यकता होगी);' – juanchopanza

+1

@AndresBucci - संपादन देखें, juanchopanza की टिप्पणी ने थोड़ा सा मेरे संपादन को हराया। असल में, वेक्टर में (टाइप *, नीलामी) कन्स्ट्रक्टर नहीं होता है, इसे एक (इटरेटर, इटरेटर) कन्स्ट्रक्टर मिल जाता है। –

0

एक कारण मैं iterators (और सी ++ 11 की वर्दी आरंभीकरण और प्रारंभकर्ता सूचियों) के साथ प्रारंभ की इस शैली का उपयोग करने कि यह कोड से अलग होने के डेटा में मदद करता है की तरह।

दोहराते हुए push_back कई बार बुरा लगता है क्योंकि मुझे इसे पुन: सक्रिय करने की जरुरत है। साथ ही, जब आपको वास्तव में डेटा के साथ कंटेनर को प्रारंभ करने की आवश्यकता होती है, तो आप डेटा की एक सूची देखना चाहते हैं, और वास्तव में कोड उत्पन्न नहीं करते हैं जो डेटा उत्पन्न करता है। मूल संस्करण में जो विधि आपने पाया वह सिद्धांत बेहतर है।

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