C ++ 11 पर स्विच कैसे करें?


35

मैं थोड़ी देर के लिए C ++ में प्रोग्रामिंग कर रहा हूं, लेकिन ज्यादातर चीजें C ++ की निम्न-स्तरीय विशेषताओं के आसपास केंद्रित हैं। मेरा मतलब है कि ज्यादातर पॉइंटर्स और कच्चे सरणियों के साथ काम करना। मुझे लगता है कि इस व्यवहार को कक्षाओं के साथ सी ++ के रूप में उपयोग किया जाता है। इसके बावजूद, मैंने केवल पहली बार सी की कोशिश की। मुझे सुखद आश्चर्य हुआ कि कैसे सी # और जावा जैसी भाषाएं इन विवरणों को दूर के मानक पुस्तकालय कक्षाओं जैसे डिक्शनरी और लिस्ट में छिपा देती हैं।

मुझे पता है कि C ++ मानक पुस्तकालय में वैक्टर, नक्शे और तार जैसे कई कंटेनर हैं और C ++ 11 केवल इसमे जोड़ता है std :: array और ranged loops।

मैं इन आधुनिक भाषा सुविधाओं का उपयोग कैसे करना सीखूं और कौन से क्षणों के लिए उपयुक्त हैं? क्या यह सही है कि आजकल C ++ में सॉफ्टवेयर इंजीनियरिंग ज्यादातर मैनुअल मेमोरी मैनेजमेंट से मुक्त है?

अंत में, मुझे नए मानक का अधिकतम उपयोग करने के लिए किस संकलक का उपयोग करना चाहिए? विजुअल स्टूडियो में उत्कृष्ट डिबगिंग टूल हैं, लेकिन यहां तक ​​कि VS2012 में भयानक C ++ 11 समर्थन है।


2
मैं कहूंगा कि VS2012 का C ++ 11 समर्थन "भयानक" थोड़ा अतिरंजित है, लेकिन यह निश्चित रूप से बेहतर हो सकता है (अनुपलब्ध प्रारंभिक सूचियां विशेष रूप से टेस्ट / टॉय कोड के लिए कष्टप्रद है)। लेकिन ध्यान दें कि उन्होंने घोषणा की कि वे वीएस के बाकी हिस्सों से स्वतंत्र रूप से कंपाइलर अपडेट करेंगे, इसलिए मुझे लगता है कि हम 2013 के वीएस2012 में काफी कुछ सी ++ 11 सुविधाओं की उम्मीद कर सकते हैं।
मार्टिन बा

3
पहले तो मैंने सोचा था कि C ++ 11 सीखने के लिए यह अजीब होगा, लेकिन यह देखते हुए कि आप अभी भी C-With-Classes भूमि में अटके हुए हैं ... एक दशक पहले मैंने Koenig / Moo की त्वरित C ​​++ पढ़ी थी । जब तक मैं वास्तव में पहले से ही टेम्प्लेट मेटा-प्रोग्रामिंग कर रहा था (मैंने इसे केवल एक समीक्षा के लिए पढ़ा था), लेकिन यह अभी भी एक रहस्योद्घाटन की तरह लगा। (मैंने इसे तब से C ++ सिखाने के लिए एक आधार के रूप में इस्तेमाल किया है।) C with Classes के साथ आने पर , पुस्तक आपको एक पूरी नई भाषा दिखा सकती है जिसे आप नहीं जानते थे कि आप अपने निपटान में थे। यह केवल 250 पृष्ठ है, और फिर आप C ++ 11-विशिष्ट के लिए जल्दी से अग्रिम कर सकते हैं, लेकिन IMO यह एक सार्थक कदम है।
sbi

4
g++ -std=c++11
fredoverflow

जवाबों:


50

सबसे पहले, अंगूठे के कुछ नियम:

  • std::unique_ptrनो-ओवरहेड स्मार्ट पॉइंटर के रूप में उपयोग करें । आपको अक्सर कच्चे पॉइंटर्स से परेशान होने की ज़रूरत नहीं है। std::shared_ptrइसी तरह ज्यादातर मामलों में अनावश्यक है। साझा स्वामित्व की इच्छा अक्सर पहली जगह में स्वामित्व के बारे में विचार की कमी को धोखा देती है।

  • std::arrayस्थैतिक-लंबाई सरणियों के लिए और std::vectorगतिशील के लिए उपयोग करें ।

  • विशेष रूप से बड़े पैमाने पर जेनेरिक एल्गोरिदम का उपयोग करें:

    • <algorithm>
    • <numeric>
    • <iterator>
    • <functional>
  • उपयोग autoऔर decltype()जहाँ भी वे पठनीयता का लाभ उठाते हैं। विशेष रूप से, जब आप किसी चीज़ को घोषित करना चाहते हैं, लेकिन एक प्रकार का जिसे आप इस बारे में परवाह नहीं करते हैं जैसे कि एक इटरेटर या जटिल टेम्पलेट प्रकार, उपयोग auto। जब आप किसी चीज को दूसरी चीज के प्रकार के संदर्भ में घोषित करना चाहते हैं, तो उपयोग करें decltype()

  • जब आप कर सकते हैं चीजों को सुरक्षित रखें। जब आपके पास एक विशेष प्रकार की चीज़ पर आक्रमण करने वालों को लागू करने के दावे हैं, तो उस तर्क को एक प्रकार में केंद्रीकृत किया जा सकता है। और यह जरूरी नहीं कि किसी रनटाइम ओवरहेड के लिए बना हो। यह भी कहे बिना जाना चाहिए कि C- शैली की जातियों ( (T)x) को अधिक स्पष्ट (और खोज योग्य!) C ++ - शैली की जातियों (जैसे, static_cast) के पक्ष में टाला जाना चाहिए ।

  • अंत में, जानिए कैसे तीन का नियम:

    • नाशक
    • कंस्ट्रक्टर को कॉपी करें
    • असाइनमेंट ऑपरेटर

    मूव कंस्ट्रक्टर और मूव असाइनमेंट ऑपरेटर को जोड़ने के साथ पांच का नियम बन गया है। और सामान्य रूप से संदर्भों को समझें और नकल से कैसे बचें।

तो यह कैसे सबसे अच्छा उपयोग करने के लिए चिह्नित करने के लिए मुश्किल है सी ++, एक जटिल भाषा है सब इसके बारे में। लेकिन अच्छे C ++ विकास की प्रथाओं को C ++ 11 के साथ मौलिक रूप से नहीं बदला है। आपको अभी भी मैन्युअल मेमोरी प्रबंधन पर मेमोरी-प्रबंधित कंटेनरों को प्राथमिकता देना चाहिए - स्मार्ट पॉइंटर्स कुशलतापूर्वक ऐसा करना आसान बनाते हैं।

मैं कहूंगा कि आधुनिक C ++ वास्तव में मैन्युअल मेमोरी प्रबंधन से मुक्त है - C ++ के मेमोरी मॉडल का लाभ यह है कि यह नियतात्मक है , न कि यह मैनुअल है। भविष्य कहनेवाला प्रदर्शन अधिक पूर्वानुमान प्रदर्शन के लिए बनाते हैं।

संकलक के रूप में, G ++ और Clang दोनों C ++ 11 सुविधाओं के संदर्भ में प्रतिस्पर्धी हैं, और तेजी से अपनी कमियों को पकड़ रहे हैं। मैं विज़ुअल स्टूडियो का उपयोग नहीं करता, इसलिए मैं न तो इसके लिए बोल सकता हूं और न ही इसके खिलाफ।

अंत में, एक नोट के बारे में std::for_each: इसे सामान्य रूप से बचें।

transform, accumulate, और erase- remove_ifअच्छे पुराने कार्य कर रहे हैं map, foldऔर filter। लेकिन for_eachयह अधिक सामान्य है, और इसलिए कम सार्थक है - यह लूपिंग के अलावा किसी भी इरादे को व्यक्त नहीं करता है । इसके अलावा, यह रेंज-आधारित के रूप में समान स्थितियों में उपयोग किया जाता है for, और पॉइंट-फ़्री होने पर भी सिंटैक्टिक रूप से भारी होता है। विचार करें:

for (const auto i : container)
    std::cout << i << '\n';

std::for_each(container.begin(), container.end(), [](int i) {
    std::cout << i << '\n';
});

for (const auto i : container)
    frobnicate(i);

std::for_each(container.begin(), container.end(), frobnicate);

6
क्या अंगूठे के इन नियमों के कुछ बाध्यकारी सिद्धांत हैं? यह सुझावों की एक अच्छी सूची की तरह लगता है, लेकिन ... Google के माध्यम से इस प्रश्न पर पहुंचने वाले एक बाहरी व्यक्ति के रूप में, आपका जवाब मुझे राजसी तरीके से C ++ 11 चुनने में कैसे मदद करता है, और इसे C ++ धुरा के चारों ओर खुद को लपेटे बिना उपयोग करें ?
रॉबर्ट हार्वे

3
सूची के लिए +1, लेकिन मेरे पास एक छोटा सा नाइटपिक है: जब (सही-सही) चेतावनी के खिलाफ std::for_eachमैंने लूप के आधार पर सीमा को सादे से बेहतर प्रतिस्थापन के रूप में उम्मीद की होगी for
फैबियो फ्रैकासी

@FabioFracassi: उफ़। मैंने इसके विपरीत करने के लिए सादा लिखा std::for_each, रेंज-आधारित नहीं । मैंने भ्रम से बचने के लिए इसे हटा दिया है।
जॉन पुरडी

1
अगर यह नहीं होता तो मैं अपडेट करता std::for_each()। जब आपके पास लैम्ब्डा होता है, तो यह निश्चित रूप से पारंपरिक forलूप से बेहतर होता है । रेंज-आधारित forलूप के साथ जो मामला नहीं हो सकता है, लेकिन आपने "रेंज-आधारित forलूप" नहीं लिखा है ।
sbi

@ एसएसबी: मेरे दिमाग में, " forलूप" शब्द में "रेंज-आधारित forलूप" शामिल है। मैंने अधिक स्पष्टीकरण और स्पष्टीकरण देने के लिए एक उदाहरण के साथ संपादित किया है, धन्यवाद।
जॉन पुरडी

12

एक प्रारंभिक बिंदु के रूप में:

  • char*तार के लिए उपयोग करना बंद करो । उपयोग करें std::stringया std::wstringबस अपने कोड को कम, अधिक पठनीय और सुरक्षित देखें
  • C- शैली सरणियों (के साथ घोषित चीजें [ ]) और उपयोग std::vectorया कुछ अन्य उपयुक्त कंटेनर वर्ग का उपयोग करना बंद करें । इसके बारे में अच्छी बातें std::vectorयह है कि यह अपनी लंबाई जानता है, यह अपनी सामग्री को साफ करता है जब यह दायरे से बाहर हो जाता है, तो इसे खत्म करना आसान है, और अधिक आइटम जोड़ने पर यह खुद को बड़ा बनाता है। लेकिन ऐसे अन्य संग्रह हैं जो आपकी परिस्थितियों के लिए बेहतर काम कर सकते हैं।
  • उपयोग करें std::unique_ptr- और std::moveलगभग तुरंत सीखें । चूंकि यह कुछ noncopyable वस्तुओं में हो सकता है, आलस्य कभी-कभी आप की ओर भेज सकते हैं std::shared_ptr- और आप के लिए कुछ वास्तविक उपयोग के मामलों में हो सकता है std::shared_ptrके रूप में अच्छी तरह से
  • उपयोग autoपुनरावृत्तियों और प्रकारों की घोषणा करते समय जो पहले की घोषणाओं पर निर्भर करते हैं (जैसे पहले आपने किसी चीज़ का वेक्टर घोषित किया था, अब आप कुछ घोषित कर रहे हैं, उपयोग करें auto)
  • एल्गोरिदम का उपयोग करें और for_eachजब भी आप कर सकते हैं "कच्चे के लिए" जब से यह आपके लूप को पढ़ने से दूसरों को ध्यान से यह निष्कर्ष निकालता है कि आप वास्तव में पूरे संग्रह पर इत्यादि कर रहे हैं। यदि आपका कंपाइलर "सीमा के लिए" का समर्थन करता है, तो इसका उपयोग करें for_each। तुच्छ एल्गोरिथ्म कॉल को जानें iota, जैसे generate,accumulate , find_ifऔर इतने पर।
  • लैम्ब्डा का प्रयोग करें - वे एल्गोरिदम का लाभ उठाने का आसान तरीका हैं। वे भी बहुत कुछ करने के लिए दरवाजा खोलते हैं।

उपयोग करने के लिए संकलक के बारे में बहुत अधिक काम न करें। VS2012 में C ++ 11 समर्थन की "भयानक, भयानक" कमी यह है कि वैरेडिक टेम्प्लेट नहीं हैं (हाँ सही है, आप बस वैरेडिक टेम्प्लेट का उपयोग करने वाले थे ) और इनिशलाइज़र {}वहाँ नहीं है। मैं भी यही चाहता हूं, लेकिन मैं शायद ही इस पर एक उपयोगी विकास उपकरण का उपयोग बंद करने जा रहा हूं।

दूसरी बात, गले लगाने के बाद std::, आरएआई सोचना शुरू करना है। कभी भी आपके पास

  • कार्रवाई शुरू
  • कार्रवाई शुरू करने से आपको मिली चीज़ों की श्रृंखला
  • क्लीनअप एक्शन जो अपवादों के मामले में भी होने की जरूरत है

फिर आपके पास क्या है एक निर्माता, कई सदस्य कार्य और एक विध्वंसक है। एक ऐसा वर्ग लिखें जो आपके लिए ध्यान रखे। आपको ctor और dtor लिखना भी नहीं आता होगा। एक लाना shared_ptrएक वर्ग के एक सदस्य चर के रूप में आरए II का एक उदाहरण है - आप नहीं लिखने स्मृति प्रबंधन कोड करते हैं, लेकिन जब आपके उदाहरण दायरे से बाहर चला जाता है, सही चीज़ें होंगी। फ़ाइलों को बंद करने, हैंडल जारी करने, ताले आदि जैसी चीजों को कवर करने की सोच का विस्तार करें और कोड आपकी आंखों के सामने सरल और छोटा (लीक को खत्म करते समय) मिलेगा।

क्या तुम सच में विश्वास है महसूस कर रहे हैं, तो पर्ज printfके पक्ष में cout, मैक्रो (से छुटकारा पाने के #defineसामान), और pimpl जैसे कुछ "उन्नत मुहावरे" सीखना शुरू करते हैं। मेरे पास प्लुरलिटी में इस पर एक पूरा पाठ्यक्रम है जिसे आप शायद उनके नि: शुल्क परीक्षण का उपयोग करके देख सकते हैं।


2
मुझे पसंद है कि आप कभी भी उसके बारे में व्यंग्यात्मक नहीं हैं कि वह जल्द ही वेरिएडिक टेम्प्लेट का उपयोग नहीं कर रहा है, लेकिन मुझे लगता है कि यूनिफ़ॉर्म इनिशियलाइज़ेशन गायब होना रोज़मर्रा की प्रोग्रामिंग के लिए वास्तव में महत्वपूर्ण है।
sbi

आरंभिक सूचियों की प्रतीक्षा नहीं कर सकते ... हम कब प्राप्त करेंगे यह जानने के लिए प्रतीक्षा कर रहे हैं ...
केट ग्रेगोरी

VS2012 में एक और महत्वपूर्ण कमी "रेवल्यू रेफरेंस v3" है, यानी ऑटोमैटिक जनरेटेड मूव कंस्ट्रक्टर और मूव असाइन।
मि। ६४

3

मैं इन आधुनिक भाषा सुविधाओं का उपयोग कैसे करना सीखूं और कौन से क्षणों के लिए उपयुक्त हैं?

प्रोग्रामिंग करके। अनुभव सीखने का सबसे अच्छा तरीका है।

C ++ 11 में बहुत सारी नई विशेषताएं हैं (ऑटो, प्रतिद्वंद्विता, नए स्मार्ट पॉइंटर्स - बस कुछ नाम रखने के लिए)। सबसे अच्छी शुरुआत सिर्फ उनका उपयोग करना शुरू करना है, और जब भी आप कर सकते हैं, उनके बारे में पढ़ें और जब भी आपको एक दिलचस्प लेख मिले।

क्या यह सही है कि आजकल C ++ में सॉफ्टवेयर इंजीनियरिंग ज्यादातर मैनुअल मेमोरी मैनेजमेंट से मुक्त है?

यह निर्भर करता है कि आपको क्या करने की आवश्यकता है। अधिकांश एप्लिकेशन स्मार्ट पॉइंटर्स के साथ दूर हो सकते हैं, और मेमोरी प्रबंधन के बारे में भूल सकते हैं। अभी भी ऐसे एप्लिकेशन हैं जो इतनी आसानी से दूर नहीं हो सकते हैं (उदाहरण के लिए यदि उन्हें प्लेसमेंट नए की आवश्यकता है, या जो भी कारण के लिए एक कस्टम मेमोरी एलोकेटर है)।

यदि आपको Qt का उपयोग करने की आवश्यकता है, तो आपको स्मृति प्रबंधन के लिए उनके नियमों का उपयोग करना होगा।

नए मानक का अधिकतम उपयोग करने के लिए मुझे किस संकलक का उपयोग करना चाहिए?

आपके पास जो कुछ भी है वह नवीनतम मानक का समर्थन करता है:

लेकिन कोई भी कंपाइलर सभी सुविधाओं का समर्थन नहीं करता है।


-7

मेरा विश्वविद्यालय अभी भी शिक्षण के लिए C ++ का उपयोग कर रहा है। मैंने 5 वर्षों के लिए C ++ के साथ प्रोग्राम किया है और अब मैं एक स्नातक छात्र हूं। बेशक, अब मैं एक बहुत जावा, रूबी आदि का उपयोग कर रहा हूं, मैं वास्तव में आपको सलाह देता हूं कि आप जावा जैसी भाषा में उन विशेषताओं के बारे में जल्दबाजी न करें। मेरे अनुभव और राय में, सी ++ की निम्न स्तर की विशेषताओं के बाद। आपको C / C ++ के साथ जेनेरिक प्रोग्रामिंग जैसे विषयों को देखना चाहिए जैसे कि टेम्प्लेट क्लास बनाना, टेम्प्लेट फ़ंक्शंस, ऑपरेटर ओवररेटेड, वर्चुअल मेथड्स, स्मार्ट एक्टर्स। ऑब्जेक्ट ओरिएंटेड डिज़ाइन पार्ट के लिए, C ++ में बहुत सारी विशेषताएं हैं और जावा मल्टी-इनहेरिटेंस की तरह नहीं है। वंशानुक्रम शक्तिशाली है लेकिन खतरनाक भी है। C ++ में ऑब्जेक्ट ओरिएंटेड डिज़ाइन का कार्यान्वयन स्तर एक अच्छा विषय भी है। इंटर प्रक्रिया संचार, सूत्रण, C ++ में भी महत्वपूर्ण हैं।

संकलक और डीबगर के लिए। मुझे पता है कि दृश्य स्टूडियो कमाल का है। लेकिन मैं वास्तव में आपको GDB, Valgrind और Make still सीखने की सलाह देता हूं, और इन उपकरणों में अच्छा होना चाहिए। Microsoft बहुत बढ़िया है, लेकिन इसने आपके लिए बहुत से काम किए हैं। एक छात्र के रूप में, आपको वास्तव में उन चीजों को सीखने की आवश्यकता है जो Microsoft ने भी आपके साथ की थीं। संकलक के लिए, जी ++ जीएनयू से अच्छा है।

आखिरकार, इतने सालों के बाद, मैं वास्तव में महसूस करता हूं, सबसे महत्वपूर्ण चीजें कच्चे स्तर की निम्न स्तर की विशेषताएं हैं। वेक्टर वास्तव में सिर्फ एक गतिशील सरणी है। ये मेरी सिफारिशें हैं, शायद कुछ व्यक्तिपरक भी हैं, जो आपको लगता है कि सही है।


6
यह प्रश्न का उत्तर कैसे देता है? प्रश्न सामान्य रूप से C ++ सीखने के बारे में नहीं है, लेकिन C ++ 11 पर स्विच करना है।
मार्टी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.