C++11
C++ language revisions |
---|
C++11, C++ प्रोग्रामिंग भाषा के लिए मानकीकरण के लिए अंतर्राष्ट्रीय संगठन/अंतर्राष्ट्रीय इंटरनेशनल इलेक्ट्रोटेक्नीकल कमीशन मानक का एक संस्करण है। C++ 11 ने C++ मानक के पूर्व संस्करण को बदल दिया, जिसे C++ 03 कहा जाता है,[1] और बाद में इसे C++14 से बदल दिया गया। नाम विनिर्देश के प्रकाशन वर्ष द्वारा भाषा संस्करणों के नामकरण की परंपरा का पालन करता है, चूंकि इसे पूर्व में C++0x नाम दिया गया था क्योंकि यह 2010 से पहले प्रकाशित होने की उम्मीद थी।[2] यद्यपि डिज़ाइन लक्ष्यों में से एक मुख्य भाषा में परिवर्तनों पर लाइब्रेरी में परिवर्तनों को प्राथमिकता देना था,[3] C++ 11 मूल भाषा में कई बदलाव करता है। कोर लैंग्वेज के जिन क्षेत्रों में ज्यादा सुधार हुआ उनमें मल्टीथ्रेडिंग सपोर्ट, सामान्य प्रोग्रामिंग सपोर्ट, यूनिफॉर्म इनिशियलाइज़ेशन और परफॉर्मेंस सम्मिलित हैं। गणितीय विशेष कार्यों के पुस्तकालय को छोड़कर, C++ मानक पुस्तकालय में भी महत्वपूर्ण परिवर्तन किए गए, जिसमें अधिकांश C++ तकनीकी रिपोर्ट 1 (TR1) पुस्तकालय (कंप्यूटर विज्ञान) सम्मिलित थे।[4] C++11 को ISO/IEC 14882:2011 के रूप में प्रकाशित किया गया था[5] सितंबर 2011 में और शुल्क के लिए उपलब्ध है। प्रकाशित C++11 मानक के समान काम करने वाला मसौदा N3337 है, दिनांक 16 जनवरी 2012;[6] इसमें C++11 मानक से केवल संपादकीय सुधार हैं।[7]
डिजाइन लक्ष्य
डिज़ाइन समिति ने C++11 को डिज़ाइन करने में कई लक्ष्यों पर टिके रहने का प्रयास किया:
- ISO/IEC 14882|C++98 और संभवतः C (प्रोग्रामिंग भाषा) के साथ स्थिरता और अनुकूलता बनाए रखें
- मूल भाषा का विस्तार करने के बजाय मानक पुस्तकालय के माध्यम से नई सुविधाओं को प्रस्तुत करना पसंद करें
- उन बदलावों को प्राथमिकता दें जो प्रोग्रामिंग तकनीक को विकसित कर सकें
- केवल विशिष्ट अनुप्रयोगों के लिए उपयोगी नई सुविधाओं को पेश करने के बजाय सिस्टम और लाइब्रेरी डिज़ाइन को सुविधाजनक बनाने के लिए C++ में सुधार करें
- पहले की असुरक्षित तकनीकों के सुरक्षित विकल्प प्रदान करके प्रकार की सुरक्षा बढ़ाएँ
- प्रदर्शन और सीधे हार्डवेयर के साथ काम करने की क्षमता बढ़ाएँ
- वास्तविक दुनिया की समस्याओं के लिए उचित समाधान प्रदान करें
- शून्य-ओवरहेड सिद्धांत लागू करें (कुछ उपयोगिताओं द्वारा आवश्यक अतिरिक्त समर्थन का उपयोग तभी किया जाना चाहिए जब उपयोगिता का उपयोग किया जाता है)
- विशेषज्ञ प्रोग्रामरों द्वारा आवश्यक किसी भी उपयोगिता को हटाए बिना सी ++ को पढ़ाने और सीखने में आसान बनाएं
शुरुआती लोगों पर ध्यान देना महत्वपूर्ण माना जाता है, क्योंकि अधिकांश कंप्यूटर प्रोग्रामर हमेशा ऐसे ही होते हैं, और क्योंकि कई शुरुआती अपने ज्ञान को कभी भी विस्तृत नहीं करते हैं, खुद को उस भाषा के पहलुओं में काम करने के लिए सीमित करते हैं जिसमें वे विशेषज्ञ होते हैं।[1]
== सी ++ कोर भाषा == के लिए एक्सटेंशन
सी ++ समिति का एक कार्य भाषा कोर का विकास है। कोर लैंग्वेज के जिन क्षेत्रों में ज्यादा सुधार हुआ उनमें थ्रेड (कंप्यूटर साइंस) सपोर्ट, जेनेरिक प्रोग्रामिंग सपोर्ट, यूनिफॉर्म इनिशियलाइज़ेशन और परफॉर्मेंस सम्मिलित हैं।
कोर लैंग्वेज रनटाइम परफॉरमेंस एन्हांसमेंट
ये भाषा सुविधाएँ मुख्य रूप से स्मृति या कम्प्यूटेशनल गति के किसी प्रकार के प्रदर्शन लाभ प्रदान करने के लिए सम्मिलित हैं।
रेवल्यू रेफरेंस और मूव कंस्ट्रक्टर्स
सी ++ 03 (और पहले) में, अस्थायी (मूल्य (कंप्यूटर विज्ञान) कहा जाता है, क्योंकि वे अक्सर असाइनमेंट के दाहिने तरफ झूठ बोलते हैं) का उद्देश्य कभी भी परिवर्तनीय नहीं होना चाहिए - जैसा कि सी में - और इन्हें अलग-अलग माना जाता है से const T&
प्रकार; फिर भी, कुछ मामलों में, टेम्परेरी को संशोधित किया जा सकता था, एक ऐसा व्यवहार जिसे एक उपयोगी बचाव का रास्ता भी माना जाता था।[8] C++11 एक नया गैर-कॉन्स्ट संदर्भ प्रकार (C++) जोड़ता है जिसे a कहा जाता है। rvalue reference, द्वारा पहचाना गया T&&
. यह उन अस्थायी वस्तुओं को संदर्भित करता है जिन्हें चलने वाले शब्दार्थों की अनुमति देने के उद्देश्य से आरंभिक होने के बाद संशोधित करने की अनुमति दी जाती है।
सी ++ 03 के साथ एक पुरानी प्रदर्शन समस्या महंगी और अनावश्यक गहरी प्रतिलिपि है जो वस्तुओं को मूल्य से पारित होने पर अंतर्निहित रूप से हो सकती है। इस मुद्दे को स्पष्ट करने के लिए, विचार करें कि a std::vector<T>
आंतरिक रूप से, परिभाषित आकार के साथ सी-शैली सरणी के चारों ओर एक आवरण है। यदि एक std::vector<T>
अस्थायी बनाया जाता है या किसी फ़ंक्शन से लौटाया जाता है, इसे केवल एक नया बनाकर संग्रहीत किया जा सकता है std::vector<T>
और इसमें सभी रावल्यू के डेटा को कॉपी करना। तब अस्थायी और उसकी सारी स्मृति नष्ट हो जाती है। (सरलता के लिए, यह चर्चा वापसी मूल्य अनुकूलन की उपेक्षा करती है।)
C++11 में, ab:More C++ Idioms/Move Constructor|move constructorका std::vector<T>
जो एक के लिए एक प्रतिद्वंद्विता संदर्भ लेता है std::vector<T>
नए में रावल्यू से आंतरिक सी-शैली सरणी में पॉइंटर को कॉपी कर सकते हैं std::vector<T>
, फिर पॉइंटर को रावल्यू के अंदर शून्य पर सेट करें। चूंकि अस्थायी का फिर से उपयोग नहीं किया जाएगा, कोई भी कोड अशक्त सूचक तक पहुंचने का प्रयास नहीं करेगा, और क्योंकि सूचक शून्य है, जब यह दायरे से बाहर हो जाता है तो इसकी मेमोरी को हटाया नहीं जाता है। इसलिए, ऑपरेशन न केवल एक गहरी प्रतिलिपि की कीमत चुकाता है, बल्कि सुरक्षित और अदृश्य है।
मानक पुस्तकालय के बाहर कोई बदलाव करने की आवश्यकता के बिना रेवल्यू संदर्भ मौजूदा कोड को प्रदर्शन लाभ प्रदान कर सकते हैं। एक लौटाने वाले फ़ंक्शन के दिए गए मान का प्रकार std::vector<T>
अस्थायी को स्पष्ट रूप से बदलने की आवश्यकता नहीं है std::vector<T> &&
मूव कंस्ट्रक्टर को आमंत्रित करने के लिए, क्योंकि अस्थायी रूप से स्वचालित रूप से प्रतिद्वंद्विता माना जाता है। (चूंकि, यदि std::vector<T>
एक सी ++ 03 संस्करण है जिसमें एक चालक कन्स्ट्रक्टर नहीं है, तो कॉपी कन्स्ट्रक्टर को एक के साथ बुलाया जाएगा const std::vector<T>&
, एक महत्वपूर्ण मेमोरी आवंटन के कारण।)
सुरक्षा कारणों से कुछ प्रतिबंध लगाए गए हैं। एक नामांकित चर को कभी भी प्रतिद्वंद्विता नहीं माना जाएगा, भले ही इसे इस तरह घोषित किया गया हो। एक प्रतिद्वंद्विता प्राप्त करने के लिए, फ़ंक्शन Template std::move()
इस्तेमाल किया जाना चाहिए। रावल्यू संदर्भों को केवल कुछ परिस्थितियों में ही संशोधित किया जा सकता है, जिसका मुख्य रूप से मूव कंस्ट्रक्टर के साथ उपयोग करने का इरादा है।
रावल्यू संदर्भों के शब्दों की प्रकृति के कारण, और लैवल्यू संदर्भों (नियमित संदर्भों) के शब्दों में कुछ संशोधन के कारण, रैवल्यू संदर्भ डेवलपर्स को सही फ़ंक्शन अग्रेषण प्रदान करने की अनुमति देते हैं। जब #Variadic टेम्पलेट्स के साथ जोड़ा जाता है, तो यह क्षमता फ़ंक्शन टेम्पलेट्स के लिए अनुमति देती है जो तर्कों को किसी अन्य फ़ंक्शन पर पूरी तरह से अग्रेषित कर सकते हैं जो उन विशेष तर्कों को लेता है। यह कन्स्ट्रक्टर पैरामीटर को अग्रेषित करने के लिए सबसे उपयोगी है, फैक्ट्री फ़ंक्शंस बनाने के लिए जो स्वचालित रूप से उन विशेष तर्कों के लिए सही कन्स्ट्रक्टर को कॉल करेगा। इसे emplace_back C++ मानक लाइब्रेरी विधियों के सेट में देखा जा सकता है।
constexpr - सामान्यीकृत स्थिर भाव
सी ++ में हमेशा निरंतर अभिव्यक्ति की अवधारणा होती है। ये ऐसे भाव हैं 3+4
वह हमेशा एक ही परिणाम देगा, संकलन समय और रन टाइम पर। लगातार अभिव्यक्तियाँ संकलक के लिए अनुकूलन के अवसर हैं, और संकलक अक्सर संकलन-समय फ़ंक्शन निष्पादन और कार्यक्रम में परिणामों को हार्डकोड करते हैं। साथ ही, कई स्थानों पर, C++ विनिर्देशन के लिए निरंतर व्यंजकों का उपयोग करने की आवश्यकता होती है। एक सरणी को परिभाषित करने के लिए निरंतर अभिव्यक्ति की आवश्यकता होती है, और गणनाकर्ता मान निरंतर अभिव्यक्ति होना चाहिए।
चूंकि, एक निरंतर अभिव्यक्ति को फ़ंक्शन कॉल या ऑब्जेक्ट कन्स्ट्रक्टर रखने की अनुमति नहीं दी गई है। तो कोड का एक टुकड़ा जितना सरल है उतना ही अमान्य है:
int get_five() {वापसी 5;}
int some_value [get_five() + 7]; // 12 पूर्णांकों की एक सरणी बनाएँ। खराब गठित सी ++
यह सी ++ 03 में मान्य नहीं था, क्योंकि get_five() + 7
स्थिर अभिव्यक्ति नहीं है। सी ++ 03 कंपाइलर के पास यह जानने का कोई तरीका नहीं है कि क्या get_five()
वास्तव में रनटाइम पर स्थिर है। सिद्धांत रूप में, यह फ़ंक्शन वैश्विक चर को प्रभावित कर सकता है, अन्य गैर-रनटाइम स्थिर कार्यों आदि को कॉल कर सकता है।
C++11 ने कीवर्ड पेश किया constexpr
, जो उपयोगकर्ता को यह गारंटी देने की अनुमति देता है कि एक फ़ंक्शन या ऑब्जेक्ट कंस्ट्रक्टर एक संकलन-समय स्थिरांक है।[9] उपरोक्त उदाहरण को निम्नानुसार फिर से लिखा जा सकता है:
constexpr int get_five () {वापसी 5;}
int some_value [get_five() + 7]; // 12 पूर्णांकों की एक सरणी बनाएँ। वैध सी ++ 11
यह संकलक को समझने और सत्यापित करने की अनुमति देता है get_five()
एक संकलन-समय स्थिरांक है।
का उपयोग करते हुए constexpr
किसी फ़ंक्शन पर कुछ सीमाएं लगाई जाती हैं कि वह फ़ंक्शन क्या कर सकता है। सबसे पहले, फ़ंक्शन में एक गैर-शून्य रिटर्न प्रकार होना चाहिए। दूसरा, फ़ंक्शन बॉडी चर घोषित नहीं कर सकती है या नए प्रकारों को परिभाषित नहीं कर सकती है। तीसरा, शरीर में केवल घोषणाएँ, अशक्त कथन और एकल वापसी कथन हो सकते हैं। ऐसे तर्क मान सम्मिलित होने चाहिए, जो तर्क प्रतिस्थापन के बाद, रिटर्न स्टेटमेंट में अभिव्यक्ति एक निरंतर अभिव्यक्ति उत्पन्न करते हैं।
C++11 से पहले, वेरिएबल्स के मानों को निरंतर एक्सप्रेशंस में इस्तेमाल किया जा सकता है, अगर वेरिएबल्स को कॉन्स घोषित किया जाता है, एक इनिशियलाइज़र होता है जो एक कॉन्स्टेंट एक्सप्रेशन होता है, और इंटीग्रल या एन्यूमरेशन टाइप का होता है। सी ++ 11 प्रतिबंध को हटा देता है कि वेरिएबल्स अभिन्न या गणना प्रकार के होने चाहिए यदि उन्हें परिभाषित किया गया है constexpr
कीवर्ड:
constexpr डबल अर्थ_गुरुत्वाकर्षण_त्वरण = 9.8; constexpr दोहरा चाँद_गुरुत्वाकर्षण_त्वरण = पृथ्वी_गुरुत्वाकर्षण_त्वरण / 6.0;
इस तरह के डेटा वेरिएबल्स निहित रूप से हैं, और एक इनिशियलाइज़र होना चाहिए जो एक निरंतर अभिव्यक्ति होना चाहिए।
उपयोगकर्ता परिभाषित प्रकारों से निरंतर अभिव्यक्ति डेटा मान बनाने के लिए, कन्स्ट्रक्टर भी घोषित किए जा सकते हैं constexpr
. ए constexpr
कन्स्ट्रक्टर के फ़ंक्शन बॉडी में केवल घोषणाएं और शून्य कथन हो सकते हैं, और वेरिएबल्स घोषित नहीं कर सकते हैं या प्रकारों को परिभाषित नहीं कर सकते हैं constexpr
समारोह। तर्क मूल्यों का अस्तित्व होना चाहिए जैसे कि, तर्क प्रतिस्थापन के बाद, यह वर्ग के सदस्यों को निरंतर अभिव्यक्ति के साथ प्रारंभ करता है। इस प्रकार के विनाशकों को छोटा होना चाहिए।
किसी भी प्रकार के लिए कॉपी कन्स्ट्रक्टर constexpr
कंस्ट्रक्टर्स को आमतौर पर एक के रूप में भी परिभाषित किया जाना चाहिए constexpr
कन्स्ट्रक्टर, प्रकार की वस्तुओं को कॉन्स्टैक्स फ़ंक्शन से मूल्य द्वारा वापस करने की अनुमति देने के लिए। किसी वर्ग का कोई भी सदस्य कार्य, जैसे कॉपी कंस्ट्रक्टर, ऑपरेटर ओवरलोड, आदि को घोषित किया जा सकता है constexpr
, जब तक वे constexpr कार्यों के लिए आवश्यकताओं को पूरा करते हैं। यह संकलक को संकलन समय पर वस्तुओं की प्रतिलिपि बनाने, उन पर संचालन करने आदि की अनुमति देता है।
यदि एक कॉन्स्टेक्स फ़ंक्शन या कंस्ट्रक्टर को उन तर्कों के साथ बुलाया जाता है जो स्थिर अभिव्यक्ति नहीं हैं, तो कॉल ऐसा व्यवहार करता है जैसे कि फ़ंक्शन कॉन्स्टेक्स नहीं था, और परिणामी मान एक स्थिर अभिव्यक्ति नहीं है। इसी तरह, यदि किसी कॉन्स्टेक्स फ़ंक्शन के रिटर्न स्टेटमेंट में अभिव्यक्ति किसी दिए गए आमंत्रण के लिए निरंतर अभिव्यक्ति का मूल्यांकन नहीं करती है, तो परिणाम निरंतर अभिव्यक्ति नहीं होता है।
constexpr
से मतभेद होना consteval
, सी ++ 20 में पेश किया गया, जिसमें बाद वाले को हमेशा एक संकलन समय स्थिरांक उत्पन्न करना चाहिए, जबकि constexpr
यह प्रतिबंध नहीं है।
सादे पुराने डेटा की परिभाषा में संशोधन
सी ++ 03 में, एक वर्ग या संरचना को सादे पुराने डेटा (पीओडी) प्रकार के रूप में माना जाने के लिए कई नियमों का पालन करना चाहिए। इस परिभाषा में फिट होने वाले प्रकार सी के साथ संगत ऑब्जेक्ट लेआउट उत्पन्न करते हैं, और उन्हें स्थिर रूप से प्रारंभ भी किया जा सकता है। C++ 03 मानक में प्रतिबंध है कि कौन से प्रकार C के साथ संगत हैं या कोई तकनीकी कारण नहीं होने के बावजूद स्थिर रूप से आरंभ किया जा सकता है, एक संकलक प्रोग्राम को स्वीकार नहीं कर सकता; अगर किसी को C++03 POD प्रकार बनाना था और एक गैर-वर्चुअल सदस्य फ़ंक्शन जोड़ना था, तो यह प्रकार अब POD प्रकार नहीं होगा, स्थिर रूप से आरंभ नहीं किया जा सकता है, और मेमोरी लेआउट में कोई बदलाव नहीं होने के बावजूद C के साथ असंगत होगा .
सी ++ 11 ने पीओडी अवधारणा को दो अलग-अलग अवधारणाओं में विभाजित करके कई पीओडी नियमों को आराम दिया: तुच्छ और मानक-लेआउट।
एक प्रकार जो तुच्छ है, उसे स्टैटिकली इनिशियलाइज़ किया जा सकता है। इसका अर्थ यह भी है कि इसके माध्यम से डेटा को कॉपी करना मान्य है memcpy
कॉपी कन्स्ट्रक्टर का उपयोग करने के बजाय। तुच्छ प्रकार का जीवनकाल तब शुरू होता है जब इसका भंडारण परिभाषित किया जाता है, न कि जब कोई निर्माणकर्ता पूरा हो जाता है।
एक तुच्छ वर्ग या संरचना को एक के रूप में परिभाषित किया गया है:
- एक मामूली डिफ़ॉल्ट कन्स्ट्रक्टर है। यह #स्पष्ट रूप से डिफॉल्ट किए गए विशेष सदस्य फ़ंक्शन का उपयोग कर सकता है (
SomeConstructor() = default;
). - ट्रिवियल कॉपी और मूव कंस्ट्रक्टर हैं, जो डिफॉल्ट सिंटैक्स का उपयोग कर सकते हैं।
- ट्रिवियल कॉपी और मूव असाइनमेंट ऑपरेटर हैं, जो डिफ़ॉल्ट सिंटैक्स का उपयोग कर सकते हैं।
- एक तुच्छ विध्वंसक है, जो आभासी नहीं होना चाहिए।
कंस्ट्रक्टर केवल तभी तुच्छ होते हैं जब कक्षा का कोई आभासी सदस्य कार्य न हो और कोई आभासी आधार वर्ग न हो। कॉपी/मूव ऑपरेशंस के लिए भी सभी गैर-स्थैतिक डेटा सदस्यों को तुच्छ होने की आवश्यकता होती है।
एक प्रकार जो मानक-लेआउट है, का अर्थ है कि यह अपने सदस्यों को इस तरह से आदेश देता है और पैक करता है जो सी के साथ संगत है। एक वर्ग या संरचना मानक-लेआउट है, परिभाषा के अनुसार, बशर्ते:
- इसका कोई आभासी कार्य नहीं है
- इसका कोई वर्चुअल बेस क्लास नहीं है
- इसके सभी गैर-स्थैतिक डेटा सदस्यों का एक ही अभिगम नियंत्रण (सार्वजनिक, निजी, संरक्षित) है
- इसके सभी गैर-स्थैतिक डेटा सदस्य, इसके आधार वर्ग में कोई भी सम्मिलित है, पदानुक्रम में एक ही वर्ग में हैं
- उपरोक्त नियम सभी आधार वर्गों और वर्ग पदानुक्रम में सभी गैर-स्थैतिक डेटा सदस्यों पर भी लागू होते हैं
- इसमें पहले परिभाषित गैर-स्थैतिक डेटा सदस्य के समान प्रकार का कोई आधार वर्ग नहीं है
एक वर्ग / संरचना / संघ को POD माना जाता है यदि यह तुच्छ, मानक-लेआउट है, और इसके सभी गैर-स्थैतिक डेटा सदस्य और आधार वर्ग POD हैं।
इन अवधारणाओं को अलग करके, दूसरे को खोए बिना एक को छोड़ना संभव हो जाता है। जटिल मूव और कॉपी कंस्ट्रक्टर वाला एक वर्ग तुच्छ नहीं हो सकता है, लेकिन यह मानक-लेआउट हो सकता है और इस प्रकार सी के साथ इंटरऑपरेट कर सकता है। इसी तरह, सार्वजनिक और निजी गैर-स्थैतिक डेटा सदस्यों वाला एक वर्ग मानक-लेआउट नहीं होगा, लेकिन यह हो सकता है तुच्छ और इस प्रकार memcpy
-योग्य।
कोर लैंग्वेज बिल्ड-टाइम परफॉर्मेंस एन्हांसमेंट
बाहरी टेम्पलेट
सी ++ 03 में, जब भी अनुवाद इकाई में पूरी तरह से निर्दिष्ट टेम्पलेट का सामना करना पड़ता है तो संकलक को टेम्पलेट को तुरंत चालू करना चाहिए। यदि टेम्पलेट को कई अनुवाद इकाइयों में एक ही प्रकार के साथ तत्काल किया जाता है, तो यह नाटकीय रूप से संकलन समय बढ़ा सकता है। C++ 03 में इसे रोकने का कोई तरीका नहीं है, इसलिए C++11 ने बाहरी डेटा घोषणाओं के अनुरूप बाहरी टेम्पलेट घोषणाएं पेश कीं।
सी ++ 03 में यह वाक्यविन्यास है कि संकलक को टेम्पलेट को तुरंत चालू करने के लिए बाध्य किया जाए:
टेम्पलेट वर्ग एसटीडी:: वेक्टर
C++11 अब यह सिंटैक्स प्रदान करता है:
बाहरी टेम्पलेट वर्ग एसटीडी:: वेक्टर
जो संकलक को इस अनुवाद इकाई में टेम्पलेट को तत्काल नहीं करने के लिए कहता है।
कोर भाषा प्रयोज्य संवर्द्धन
भाषा को उपयोग में आसान बनाने के प्राथमिक उद्देश्य के लिए ये सुविधाएं सम्मिलित हैं। ये प्रकार की सुरक्षा में सुधार कर सकते हैं, कोड पुनरावृत्ति को कम कर सकते हैं, गलत कोड की संभावना कम कर सकते हैं, आदि।
प्रारंभकर्ता सूचियां
सी ++ 03 ने सी से प्रारंभकर्ता-सूची सुविधा को विरासत में मिला है। संरचना में सदस्यों की परिभाषाओं के क्रम में एक संरचना या सरणी को ब्रेसिज़ में तर्कों की एक सूची दी जाती है। ये इनिशियलाइज़र-सूचियाँ पुनरावर्ती हैं, इसलिए अन्य स्ट्रक्चर वाले स्ट्रक्चर या स्ट्रक्चर का एक सरणी उनका उपयोग कर सकता है।
संरचना वस्तु {
पहले तैरना; इंट सेकंड;
};
वस्तु अदिश = {0.43f, 10}; // एक वस्तु, पहले = 0.43f और दूसरी = 10 के साथ ऑब्जेक्ट ऐरे [] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // तीन वस्तुओं की एक सरणी
यह स्थैतिक सूचियों के लिए बहुत उपयोगी है, या किसी संरचना को कुछ मूल्य के लिए आरंभ करना है। सी ++ किसी ऑब्जेक्ट को प्रारंभ करने के लिए कन्स्ट्रक्टर भी प्रदान करता है, लेकिन वे अक्सर प्रारंभिक सूची के रूप में सुविधाजनक नहीं होते हैं। चूंकि, सी ++ 03 प्रारंभिक-सूचियों को केवल उन संरचनाओं और कक्षाओं पर अनुमति देता है जो सादा पुराने डेटा (पीओडी) परिभाषा के अनुरूप हैं; सी ++ 11 प्रारंभकर्ता-सूचियों को बढ़ाता है, इसलिए इन्हें मानक कंटेनर समेत सभी वर्गों के लिए उपयोग किया जा सकता है std::vector
.
C++11 अवधारणा को एक टेम्प्लेट से बांधता है, जिसे कहा जाता है std::initializer_list
. यह कंस्ट्रक्टर्स और अन्य फ़ंक्शंस को इनिशियलाइज़र-सूचियों को पैरामीटर के रूप में लेने की अनुमति देता है। उदाहरण के लिए:
क्लास सीक्वेंस क्लास { जनता:
अनुक्रम क्लास (एसटीडी :: प्रारंभकर्ता_सूची <int> सूची);
};
यह अनुमति देता है SequenceClass
पूर्णांकों के अनुक्रम से निर्मित होना, जैसे:
सीक्वेंस क्लास some_var = {1, 4, 5, 6};
यह कंस्ट्रक्टर एक विशेष प्रकार का कंस्ट्रक्टर है, जिसे इनिशियलाइज़र-लिस्ट-कन्स्ट्रक्टर कहा जाता है। ऐसे कन्स्ट्रक्टर वाले वर्गों को विशेष रूप से वर्दी प्रारंभिकरण के दौरान माना जाता है (देखें # वर्दी प्रारंभिकरण)
टेम्पलेट वर्ग std::initializer_list<>
एक प्रथम श्रेणी का नागरिक है | प्रथम श्रेणी का C++11 मानक पुस्तकालय प्रकार। वे C++11 कंपाइलर के उपयोग के माध्यम से स्थिर रूप से निर्मित किए जा सकते हैं {}
ऐसे संदर्भों में एक प्रकार के नाम के बिना सिंटैक्स जहां ऐसे ब्रेसिज़ a को घटाएंगे std::initializer_list
, या जैसे प्रकार को स्पष्ट रूप से निर्दिष्ट करके std::initializer_list<SomeType>{args}
(और इसी तरह निर्माण सिंटैक्स की अन्य किस्मों के लिए)।
सूची को एक बार बनाने के बाद कॉपी किया जा सकता है, जो सस्ता है और कॉपी-दर-संदर्भ के रूप में कार्य करेगा (वर्ग आमतौर पर प्रारंभ/अंत पॉइंटर्स की एक जोड़ी के रूप में कार्यान्वित किया जाता है)। एक std::initializer_list
स्थिर है: एक बार इसके सदस्यों को बनाया जाने के बाद बदला नहीं जा सकता है, और न ही उन सदस्यों में डेटा बदला जा सकता है (जो उनसे आगे बढ़ने से नियम बनाते हैं, कक्षा के सदस्यों में प्रतियों की आवश्यकता होती है, आदि)।
यद्यपि इसका निर्माण विशेष रूप से संकलक द्वारा किया जाता है, a std::initializer_list
एक वास्तविक प्रकार है, और इसलिए इसका उपयोग क्लास कंस्ट्रक्टर के अलावा अन्य स्थानों पर भी किया जा सकता है। नियमित कार्य टाइप किए जा सकते हैं std::initializer_list
एस तर्क के रूप में। उदाहरण के लिए:
शून्य function_name (एसटीडी :: प्रारंभकर्ता_सूची <फ्लोट> सूची); // नकल करना सस्ता है; ऊपर देखें
function_name ({1.0f, -3.45f, -0.4f});
मानक पुस्तकालय में इसके उदाहरणों में सम्मिलित हैं std::min()
और std::max()
टेम्पलेट्स ले रहा है std::initializer_list
संख्यात्मक प्रकार का।
मानक कंटेनरों को इन तरीकों से भी आरंभ किया जा सकता है:
एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी = {xyzzy, प्लग, abracadabra}; एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी ({xyzzy, प्लग, abracadabra}); एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी {xyzzy, प्लग, abracadabra}; // नीचे यूनिफ़ॉर्म इनिशियलाइज़ेशन देखें
यूनिफ़ॉर्म इनिशियलाइज़ेशन
सी ++ 03 में प्रारंभिक प्रकारों के साथ कई समस्याएं हैं। ऐसा करने के कई तरीके सम्मिलित हैं, और कुछ परस्पर विनिमय करने पर अलग-अलग परिणाम देते हैं। उदाहरण के लिए, पारंपरिक कन्स्ट्रक्टर सिंटैक्स, फ़ंक्शन घोषणा की तरह दिख सकता है, और यह सुनिश्चित करने के लिए कदम उठाए जाने चाहिए कि संकलक का सबसे परेशान पार्स नियम इस तरह की गलती नहीं करेगा। केवल समुच्चय और POD प्रकारों को कुल प्रारंभकर्ताओं के साथ प्रारंभ किया जा सकता है (का उपयोग करके SomeType var = {/*stuff*/};
).
C++11 एक सिंटैक्स प्रदान करता है जो किसी भी वस्तु पर काम करने वाले पूरी तरह से समान प्रकार के इनिशियलाइज़ेशन की अनुमति देता है। यह प्रारंभकर्ता सूची सिंटैक्स पर फैलता है:
स्ट्रक्चर बेसिकस्ट्रक्चर {
इंट एक्स; डबल वाई;
};
संरचना AltStruct {
AltStruct(int x, डबल y) : x_{x} , Y y} {}
निजी:
इंट x_; डबल वाई_;
};
बेसिक स्ट्रक्चर var1{5, 3.2}; AltStruct var2{2, 4.3};
का आरंभीकरण var1
व्यवहार करता है जैसे कि यह कुल-प्रारंभिकरण था। यही है, किसी ऑब्जेक्ट के प्रत्येक डेटा सदस्य, बदले में, प्रारंभकर्ता-सूची से संबंधित मान के साथ प्रतिलिपि-प्रारंभिक किया जाएगा। जहां आवश्यक हो वहां निहित प्रकार के रूपांतरण का उपयोग किया जाएगा। यदि कोई रूपांतरण सम्मिलित नहीं है, या केवल एक संकुचित रूपांतरण सम्मिलित है, तो प्रोग्राम खराब रूप से बना हुआ है। का आरंभीकरण var2
कंस्ट्रक्टर को आमंत्रित करता है।
कोई यह भी कर सकता है:
संरचना IdString
{
एसटीडी :: स्ट्रिंग नाम; इंट पहचानकर्ता;
};
आईडीस्ट्रिंग get_string () {
वापसी {फू, 42}; // स्पष्ट प्रकार की कमी पर ध्यान दें।
}
यूनिफ़ॉर्म इनिशियलाइज़ेशन कंस्ट्रक्टर सिंटैक्स को प्रतिस्थापित नहीं करता है, जिसकी अभी भी कई बार आवश्यकता होती है। यदि किसी वर्ग में प्रारंभकर्ता सूची कन्स्ट्रक्टर है (TypeName(initializer_list<SomeType>);
), तो यह निर्माण के अन्य रूपों पर प्राथमिकता लेता है, बशर्ते प्रारंभकर्ता सूची अनुक्रम कन्स्ट्रक्टर के प्रकार के अनुरूप हो। सी ++ 11 का संस्करण std::vector
इसके टेम्पलेट प्रकार के लिए प्रारंभकर्ता सूची कन्स्ट्रक्टर है। इस प्रकार यह कोड:
एसटीडी :: वेक्टर <int> the_vec {4};
इनिशियलाइज़र लिस्ट कंस्ट्रक्टर को कॉल करेगा, न कि कंस्ट्रक्टर को std::vector
जो एक आकार पैरामीटर लेता है और उस आकार के साथ वेक्टर बनाता है। बाद वाले कंस्ट्रक्टर तक पहुंचने के लिए, उपयोगकर्ता को सीधे मानक कंस्ट्रक्टर सिंटैक्स का उपयोग करने की आवश्यकता होगी।
टाइप अनुमान
सी ++ 03 (और सी) में, एक चर का उपयोग करने के लिए, इसके प्रकार को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए। चूंकि, टेम्प्लेट प्रकार और टेम्प्लेट मेटाप्रोग्रामिंग तकनीकों के आगमन के साथ, किसी चीज़ का प्रकार, विशेष रूप से किसी फ़ंक्शन का अच्छी तरह से परिभाषित वापसी मूल्य, आसानी से व्यक्त नहीं किया जा सकता है। इस प्रकार, इंटरमीडिएट्स को वेरिएबल्स में स्टोर करना मुश्किल है, संभवतः किसी दिए गए मेटाप्रोग्रामिंग लाइब्रेरी के इंटर्नल्स के ज्ञान की आवश्यकता है।
सी ++ 11 इसे दो तरीकों से कम करने की अनुमति देता है। सबसे पहले, एक स्पष्ट प्रारंभ के साथ एक चर की परिभाषा का उपयोग कर सकते हैं auto
कीवर्ड।[10][11] यह विशिष्ट प्रकार के प्रारंभकर्ता का एक चर बनाता है:
ऑटो some_strange_callable_type = std::bind(&some_function, _2, _1, some_object); ऑटो अन्य_वैरिएबल = 5;
के जैसा some_strange_callable_type
बस वह है जो विशेष टेम्प्लेट फ़ंक्शन ओवरराइड करता है std::bind
उन विशेष तर्कों के लिए रिटर्न। इस प्रकार को संकलक द्वारा अपने सिमेंटिक विश्लेषण कर्तव्यों के भाग के रूप में आसानी से निर्धारित किया जाता है, लेकिन उपयोगकर्ता के लिए निरीक्षण पर निर्धारित करना आसान नहीं है।
के जैसा other_variable
भी अच्छी तरह से परिभाषित है, लेकिन उपयोगकर्ता के लिए यह निर्धारित करना आसान है। यह है एक int
, जो पूर्णांक शाब्दिक के समान प्रकार है।
यह कीवर्ड का उपयोग auto
सी ++ में इस कीवर्ड के शब्दार्थ का पुन: उपयोग किया जाता है, जो मूल रूप से टाइपलेस पूर्ववर्ती भाषा बी (प्रोग्रामिंग लैंग्वेज) में उपयोग किया गया था # एक अनपेक्षित स्वचालित चर परिभाषा को दर्शाने की संबंधित भूमिका में उदाहरण।
आगे, कीवर्ड decltype
संकलन-समय पर अभिव्यक्ति के प्रकार को निर्धारित करने के लिए उपयोग किया जा सकता है। उदाहरण के लिए:
int some_int; decltype (some_int) अन्य_इंटीजर_वेरिएबल = 5;
के साथ मिलकर यह अधिक उपयोगी है auto
, क्योंकि auto चर का प्रकार केवल संकलक के लिए जाना जाता है। चूंकि, decltype
कोड में अभिव्यक्तियों के लिए भी बहुत उपयोगी हो सकता है जो ऑपरेटर ओवरलोडिंग और विशेष प्रकारों का भारी उपयोग करता है।
auto
कोड की वाचालता को कम करने के लिए भी उपयोगी है। उदाहरण के लिए, लिखने के बजाय
for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
प्रोग्रामर छोटे का उपयोग कर सकता है
के लिए (ऑटो आईटीआर = myvec.cbegin (); आईटीआर! = myvec.cend (); ++ आईटीआर)
जिसे और अधिक संकुचित किया जा सकता है क्योंकि myvec पुनरावृत्तियों को शुरू/समाप्त करता है:
के लिए (स्थिरांक ऑटो और x: myvec)
यह अंतर बढ़ता है क्योंकि प्रोग्रामर नेस्ट कंटेनरों को शुरू करता है, चूंकि ऐसे मामलों में typedef
कोड की मात्रा कम करने का एक अच्छा तरीका है।
द्वारा दर्शाया गया प्रकार decltype
द्वारा निकाले गए प्रकार से भिन्न हो सकते हैं auto
.
- सम्मिलित <वेक्टर>
मुख्य प्रवेश बिंदु() {
स्थिरांक एसटीडी :: वेक्टर वी (1); ऑटो ए = वी [0]; // a का प्रकार int है डिक्लेटाइप (वी [0]) बी = 1; // b का प्रकार const int& है, जिसका रिटर्न प्रकार है // एसटीडी :: वेक्टर <int> :: ऑपरेटर [] (size_type) स्थिरांक ऑटो सी = 0; // c का प्रकार int है ऑटो डी = सी; // डी में टाइप इंट है डिक्लेटाइप (सी) ई; // ई में टाइप इंट है, सी द्वारा नामित इकाई का प्रकार decltype ((सी)) एफ = सी; // f का प्रकार int& है, क्योंकि (c) एक लवल्यू है डिक्लेटाइप (0) जी; // g का प्रकार int है, क्योंकि 0 एक प्रतिद्वंद्विता है
}
लूप के लिए रेंज आधारित
C++11 के सिंटैक्स का विस्तार करता है for
तत्वों की एक श्रृंखला पर आसान पुनरावृत्ति की अनुमति देने के लिए कथन:
int my_array [5] = {1, 2, 3, 4, 5}; // my_array में प्रत्येक तत्व का मान दोगुना करें: के लिए (int और x: my_array)
एक्स * = 2;
// समान लेकिन सरणी तत्वों के लिए प्रकार अनुमान का भी उपयोग करना के लिए (ऑटो और एक्स: my_array)
एक्स * = 2;
का यह रूप for
, जिसे "श्रेणी-आधारित के लिए" कहा जाता है, सूची में प्रत्येक तत्व पर पुनरावृति करेगा। यह सी-स्टाइल सरणियों, इनिशियलाइज़र सूचियों और किसी भी प्रकार के लिए काम करेगा begin()
और end()
इसके लिए परिभाषित कार्य जो पुनरावृत्तियों को लौटाते हैं। आरंभ/समाप्त जोड़े वाले सभी मानक लाइब्रेरी कंटेनर श्रेणी-आधारित के लिए कथन के साथ काम करेंगे।
लैम्ब्डा फ़ंक्शंस और एक्सप्रेशन
C++11 अनाम कार्यों को बनाने की क्षमता प्रदान करता है, जिसे लैम्ब्डा फ़ंक्शन कहा जाता है।[12]
इन्हें निम्नानुसार परिभाषित किया गया है:
[](int x, int y) -> int {वापसी x + y; }
वापसी प्रकार (-> int
इस उदाहरण में) जब तक सभी को छोड़ा जा सकता है return
भाव एक ही प्रकार लौटाते हैं।
एक लैम्ब्डा वैकल्पिक रूप से क्लोजर (कंप्यूटर साइंस) हो सकता है।
वैकल्पिक फ़ंक्शन सिंटैक्स
सी (प्रोग्रामिंग लैंग्वेज) फंक्शन डिक्लेरेशन सिंटैक्स सी लैंग्वेज के फीचर सेट के लिए पूरी तरह से पर्याप्त था। चूंकि सी ++ सी से विकसित हुआ, इसने मूल सिंटैक्स रखा और जहां आवश्यक हो वहां इसे बढ़ाया। चूंकि, जैसे-जैसे C++ अधिक जटिल होता गया, इसने कई सीमाओं को उजागर किया, विशेष रूप से टेम्पलेट फ़ंक्शन घोषणाओं के संबंध में। उदाहरण के लिए, सी ++ 03 में यह अमान्य है:
टेम्पलेट <कक्षा एलएचएस, कक्षा आरएचएस>
Ret Add_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} //Ret को lhs+rhs का प्रकार होना चाहिए
प्ररूप Ret
जो भी प्रकार का जोड़ है Lhs
और Rhs
उत्पादन करेंगे। उपरोक्त C++11 की कार्यक्षमता के साथ भी decltype
, ऐसा नहीं हो सकता:
टेम्पलेट <कक्षा एलएचएस, कक्षा आरएचएस>
decltype(lhs+rhs) Add_func(const Lhs &lhs, const Rhs &rhs) {वापसी lhs + rhs;} // C++11 मान्य नहीं है
यह वैध सी ++ नहीं है क्योंकि lhs
और rhs
अभी तक परिभाषित नहीं किया गया है; वे तब तक वैध पहचानकर्ता नहीं होंगे जब तक कि पार्सर ने बाकी फ़ंक्शन प्रोटोटाइप को पार्स नहीं किया हो।
इसके आसपास काम करने के लिए, सी ++ 11 ने अनुगामी-रिटर्न-प्रकार के साथ एक नया फ़ंक्शन डिक्लेरेशन सिंटैक्स पेश किया:[13]
टेम्पलेट
ऑटो एडिंग_फंक (स्थिरांक एलएचएस और एलएचएस, स्थिरांक आरएचएस और आरएचएस) -> decltype (एलएचएस + आरएचएस) {वापसी एलएचएस + आरएचएस;}
इस सिंटैक्स का उपयोग अधिक सांसारिक कार्य घोषणाओं और परिभाषाओं के लिए किया जा सकता है:
स्ट्रक्चर समस्ट्रक्चर{
ऑटो func_name (int x, int y) -> int;
};
ऑटो कुछ संरचना :: func_name (int x, int y) -> int {
वापसी एक्स + वाई;
}
इस मामले में "ऑटो" कीवर्ड का उपयोग सिंटैक्स का हिस्सा है और सी ++ 11 में स्वचालित प्रकार की कटौती नहीं करता है। चूंकि, C ++ 14 से शुरू होकर, अनुगामी रिटर्न प्रकार को पूरी तरह से हटाया जा सकता है और कंपाइलर रिटर्न प्रकार को स्वचालित रूप से घटा देगा।[14]
वस्तु निर्माण में सुधार
सी ++ 03 में, कक्षा के रचनाकारों को उस वर्ग की प्रारंभिक सूची में अन्य कन्स्ट्रक्टरों को कॉल करने की अनुमति नहीं है। प्रत्येक कंस्ट्रक्टर को अपने सभी वर्ग सदस्यों का निर्माण स्वयं करना चाहिए या निम्नानुसार एक सामान्य सदस्य फ़ंक्शन को कॉल करना चाहिए:
क्लास समटाइप { जनता:
कुछ प्रकार (int new_number) { निर्माण (नया_नंबर); }
कुछ प्रकार () { निर्माण (42); }
निजी:
शून्य निर्माण (int new_number) { संख्या = नया_नंबर; }
इंट संख्या;
};
बेस क्लास के कंस्ट्रक्टर सीधे व्युत्पन्न कक्षाओं के संपर्क में नहीं आ सकते हैं; बेस क्लास कंस्ट्रक्टर उपयुक्त होने पर भी प्रत्येक व्युत्पन्न वर्ग को कंस्ट्रक्टर को लागू करना चाहिए। उन सदस्यों की घोषणा के स्थल पर कक्षाओं के गैर-निरंतर डेटा सदस्यों को प्रारंभ नहीं किया जा सकता है। इन्हें केवल एक कंस्ट्रक्टर में इनिशियलाइज़ किया जा सकता है।
C++11 इन सभी समस्याओं का समाधान प्रदान करता है।
सी ++ 11 कंस्ट्रक्टर्स को अन्य पीयर कंस्ट्रक्टर्स (जिसे प्रतिनिधिमंडल (प्रोग्रामिंग) कहा जाता है) को कॉल करने की अनुमति देता है। यह कंस्ट्रक्टरों को कम से कम जोड़े गए कोड के साथ दूसरे कंस्ट्रक्टर के व्यवहार का उपयोग करने की अनुमति देता है। डेलिगेशन का उपयोग अन्य भाषाओं में किया गया है, उदाहरण के लिए, जावा (प्रोग्रामिंग भाषा) और उद्देश्य सी।
यह सिंटैक्स इस प्रकार है:
क्लास समटाइप {
इंट संख्या;
जनता:
कुछ प्रकार (int new_number): संख्या (new_number) {} कुछ प्रकार (): कुछ प्रकार (42) {}
};
ध्यान दें कि, इस मामले में, वही प्रभाव बनाकर हासिल किया जा सकता था new_number
एक डिफ़ॉल्ट पैरामीटर। नया सिंटैक्स, चूंकि, इंटरफ़ेस के बजाय कार्यान्वयन में डिफ़ॉल्ट मान (42) को व्यक्त करने की अनुमति देता है - लाइब्रेरी कोड के अनुरक्षकों के लिए एक लाभ क्योंकि फ़ंक्शन पैरामीटर के लिए डिफ़ॉल्ट मान कॉल साइट्स के लिए "बेक्ड इन" हैं, जबकि कन्स्ट्रक्टर प्रतिनिधिमंडल अनुमति देता है पुस्तकालय का उपयोग करके कोड के पुनर्संकलन के बिना मूल्य को बदला जाना है।
यह एक चेतावनी के साथ आता है: सी ++ 03 किसी ऑब्जेक्ट को तब बनाया जाता है जब उसका कन्स्ट्रक्टर निष्पादित करना समाप्त कर देता है, लेकिन सी ++ 11 किसी भी कन्स्ट्रक्टर के निष्पादन को समाप्त करने के बाद निर्मित ऑब्जेक्ट पर विचार करता है। चूंकि कई कंस्ट्रक्टर्स को निष्पादित करने की अनुमति दी जाएगी, इसका मतलब यह होगा कि प्रत्येक डेलिगेटिंग कंस्ट्रक्टर अपने स्वयं के प्रकार के पूर्ण रूप से निर्मित ऑब्जेक्ट पर निष्पादित होगा। डिराइव्ड क्लास कंस्ट्रक्टर अपने बेस क्लास में सभी डेलिगेशन पूरा होने के बाद निष्पादित करेंगे।
बेस-क्लास कंस्ट्रक्टर्स के लिए, C ++ 11 एक क्लास को यह निर्दिष्ट करने की अनुमति देता है कि बेस क्लास कंस्ट्रक्टर्स को इनहेरिट किया जाएगा। इस प्रकार, सी ++ 11 कंपाइलर इनहेरिटेंस करने के लिए कोड उत्पन्न करेगा और व्युत्पन्न वर्ग को बेस क्लास में अग्रेषित करेगा। यह एक ऑल-ऑर-नथिंग फीचर है: या तो उस बेस क्लास के सभी कंस्ट्रक्टर्स को फॉरवर्ड किया जाता है या उनमें से कोई भी नहीं है। साथ ही, एक इनहेरिटेड कंस्ट्रक्टर का नाम रिज़ॉल्यूशन (प्रोग्रामिंग लैंग्वेज) # नाम मास्किंग होगा यदि यह व्युत्पन्न वर्ग के एक कंस्ट्रक्टर के हस्ताक्षर से मेल खाता है, और कई इनहेरिटेंस के लिए प्रतिबंध सम्मिलित हैं: क्लास कंस्ट्रक्टर्स मल्टीपल इनहेरिटेंस नहीं हो सकते # डायमंड प्रॉब्लम।
वाक्य रचना इस प्रकार है:
क्लास बेस क्लास { जनता:
बेसक्लास (इंट वैल्यू);
};
वर्ग व्युत्पन्न वर्ग: सार्वजनिक आधार वर्ग { जनता:
बेस क्लास का उपयोग :: बेस क्लास;
};
सदस्य आरंभीकरण के लिए, C++11 इस सिंटैक्स की अनुमति देता है:
क्लास समक्लास { जनता:
कुछ क्लास () {} स्पष्ट कुछ क्लास (int new_value): मान (new_value) {}
निजी:
इंट वैल्यू = 5;
};
क्लास का कोई भी कंस्ट्रक्टर इनिशियलाइज़ होगा value
5 के साथ, यदि कंस्ट्रक्टर अपने स्वयं के आरंभीकरण को ओवरराइड नहीं करता है। तो उपरोक्त खाली कंस्ट्रक्टर इनिशियलाइज़ हो जाएगा value
जैसा कि क्लास की परिभाषा बताती है, लेकिन एक इंट लेने वाला कंस्ट्रक्टर इसे दिए गए पैरामीटर के लिए इनिशियलाइज़ करेगा।
यह ऊपर दिखाए गए असाइनमेंट इनिशियलाइज़ेशन के बजाय कंस्ट्रक्टर या यूनिफ़ॉर्म इनिशियलाइज़ेशन का भी उपयोग कर सकता है।
स्पष्ट ओवरराइड और अंतिम
सी ++ 03 में, गलती से एक नया वर्चुअल फ़ंक्शन बनाना संभव है, जब कोई बेस क्लास फ़ंक्शन को ओवरराइड करने का इरादा रखता है। उदाहरण के लिए:
संरचना आधार {
वर्चुअल शून्य some_func (फ्लोट);
};
संरचना व्युत्पन्न: आधार {
आभासी शून्य some_func (int);
};
मान लीजिए Derived::some_func
बेस क्लास संस्करण को बदलने का इरादा है। लेकिन इसके बजाय, क्योंकि इसमें एक अलग प्रकार का हस्ताक्षर है, यह दूसरा वर्चुअल फ़ंक्शन बनाता है। यह एक आम समस्या है, खासकर जब कोई उपयोगकर्ता बेस क्लास को संशोधित करने जाता है।
C++11 इस समस्या को हल करने के लिए सिंटैक्स प्रदान करता है।
संरचना आधार {
वर्चुअल शून्य some_func (फ्लोट);
};
संरचना व्युत्पन्न: आधार {
वर्चुअल शून्य some_func (int) ओवरराइड; // खराब गठित - बेस क्लास विधि को ओवरराइड नहीं करता है
};
override
e> विशेष पहचानकर्ता का अर्थ है कि संकलक यह देखने के लिए आधार वर्ग (तों) की जाँच करेगा कि क्या इस सटीक हस्ताक्षर के साथ कोई आभासी कार्य है। और अगर वहाँ नहीं है, तो संकलक एक त्रुटि का संकेत देगा।
सी ++ 11 कक्षाओं से विरासत को रोकने या व्युत्पन्न कक्षाओं में ओवरराइडिंग विधियों को रोकने की क्षमता भी जोड़ता है। यह विशेष पहचानकर्ता के साथ किया जाता है final
. उदाहरण के लिए:
स्ट्रक्चर बेस1 फाइनल { };
संरचना व्युत्पन्न 1: बेस 1 {}; // गलत तरीके से बनाया गया है क्योंकि वर्ग बेस 1 को अंतिम रूप से चिह्नित किया गया है
संरचना आधार2 {
आभासी शून्य च () अंतिम;
};
संरचना व्युत्पन्न 2: बेस 2 {
शून्य च (); // गलत तरीके से बनाया गया है क्योंकि वर्चुअल फ़ंक्शन Base2::f को अंतिम रूप से चिह्नित किया गया है
};
इस उदाहरण में, virtual void f() final;
बयान एक नया वर्चुअल फ़ंक्शन घोषित करता है, लेकिन यह व्युत्पन्न कक्षाओं को इसे ओवरराइड करने से भी रोकता है। यह व्युत्पन्न कक्षाओं को उस विशेष फ़ंक्शन नाम और पैरामीटर संयोजन का उपयोग करने से रोकने का प्रभाव भी रखता है।
ध्यान दें कि न तो override
और न final
भाषा कीवर्ड हैं। वे घोषणाकर्ता विशेषताओं के लिए तकनीकी रूप से पहचानकर्ता हैं:
- वे केवल उन विशिष्ट अनुगामी संदर्भों में उपयोग किए जाने पर विशेषताओं के रूप में विशेष अर्थ प्राप्त करते हैं (सभी प्रकार के विनिर्देशक, एक्सेस विनिर्देशक, सदस्य घोषणाएँ (संरचना, वर्ग और एनम प्रकार के लिए) और घोषणाकर्ता विनिर्देशक, लेकिन प्रत्येक घोषणाकर्ता के आरंभीकरण या कोड कार्यान्वयन से पहले घोषणाकर्ताओं की अल्पविराम से अलग की गई सूची);
- वे घोषित प्रकार के हस्ताक्षर में परिवर्तन नहीं करते हैं और किसी भी दायरे में किसी भी नए पहचानकर्ता को घोषित या ओवरराइड नहीं करते हैं;
- मान्यता प्राप्त और स्वीकृत घोषणाकर्ता विशेषताओं को सी ++ के भविष्य के संस्करणों में विस्तारित किया जा सकता है (कुछ संकलक-विशिष्ट एक्सटेंशन पहले से ही जोड़े गए घोषणाकर्ता विशेषताओं को पहचानते हैं, कोड जनरेशन विकल्प या संकलक को अनुकूलन संकेत प्रदान करने के लिए, या संकलित कोड में अतिरिक्त डेटा उत्पन्न करने के लिए, इरादा डिबगर्स, लिंकर्स, और संकलित कोड की तैनाती के लिए, या अतिरिक्त सिस्टम-विशिष्ट सुरक्षा विशेषताएँ प्रदान करने के लिए, या रनटाइम पर प्रतिबिंब (कंप्यूटर विज्ञान) क्षमताओं को बढ़ाने के लिए, या अन्य प्रोग्रामिंग भाषाओं और रनटाइम सिस्टम के साथ इंटरऑपरेबिलिटी के लिए अतिरिक्त बाध्यकारी जानकारी प्रदान करने के लिए; घोषणाकर्ता विशेषता पहचानकर्ता के बाद ये एक्सटेंशन कोष्ठक के बीच पैरामीटर ले सकते हैं; एएनएसआई अनुरूपता के लिए, इन कंपाइलर-विशिष्ट एक्सटेंशन को डबल अंडरस्कोर उपसर्ग सम्मेलन का उपयोग करना चाहिए)।
- किसी अन्य स्थान पर, वे नई घोषणाओं के लिए मान्य पहचानकर्ता हो सकते हैं (और बाद में उपयोग करें यदि वे सुलभ हैं)।
अशक्त सूचक स्थिरांक
इस खंड और अकेले इस खंड के प्रयोजनों के लिए, प्रत्येक घटना "0
" का अर्थ है "एक स्थिर अभिव्यक्ति जो इसका मूल्यांकन करती है 0
, जो int प्रकार का है"। वास्तव में, निरंतर अभिव्यक्ति किसी भी अभिन्न प्रकार की हो सकती है।
1972 में सी की सुबह के बाद से, निरंतर 0
निरंतर पूर्णांक और अशक्त सूचक स्थिरांक की दोहरी भूमिका रही है। के दोहरे अर्थ में निहित अस्पष्टता 0
सी में प्रीप्रोसेसर मैक्रो का उपयोग करके निपटाया गया था NULL
, जो आमतौर पर या तो तक फैलता है ((void*)0)
या 0
. सी ++ से निहित रूपांतरण को रोकता है void *
अन्य सूचक प्रकारों के लिए, इस प्रकार कास्टिंग के लाभ को दूर करना 0
को void *
. परिणामस्वरूप, केवल 0
शून्य सूचक स्थिरांक के रूप में अनुमत है। यह समारोह अधिभार के साथ खराब तरीके से इंटरैक्ट करता है:
शून्य फू (चार *); शून्य फू (इंट);
अगर NULL
परिभाषित किया जाता है 0
(जो आमतौर पर C++ में होता है), कथन foo(NULL);
कॉल करेंगे foo(int)
, जो लगभग निश्चित रूप से वह नहीं है जो प्रोग्रामर का इरादा था, और न कि कोड के सतही पढ़ने से क्या पता चलता है।
सी ++ 11 एक विशिष्ट शून्य सूचक स्थिरांक के रूप में कार्य करने के लिए एक नया कीवर्ड पेश करके इसे ठीक करता है: nullptr
. यह प्रकार का है nullptr_t
, जो निहित रूप से परिवर्तनीय है और किसी भी सूचक प्रकार या सूचक-से-सदस्य प्रकार से तुलनीय है। इसके अलावा, यह अंतर्निहित रूप से परिवर्तनीय या अभिन्न प्रकारों से तुलनीय नहीं है bool
. जबकि मूल प्रस्ताव में निर्दिष्ट किया गया था कि प्रकार का एक प्रतिद्वंद्विता nullptr_t
में परिवर्तनीय नहीं होना चाहिए bool
, कोर लैंग्वेज वर्किंग ग्रुप ने तय किया कि इस तरह का रूपांतरण नियमित पॉइंटर प्रकारों के साथ संगति के लिए वांछनीय होगा। जून 2008 में प्रस्तावित शब्द परिवर्तन को सर्वसम्मति से वर्किंग पेपर में वोट दिया गया था।[2] इसी तरह का प्रस्ताव सी स्टैंडर्ड वर्किंग ग्रुप के लिए भी लाया गया है।[15]
पश्चगामी संगतता कारणों के लिए, 0
एक वैध शून्य सूचक स्थिर रहता है।
चार * पीसी = नलप्टर; // ठीक int *pi = nullptr; // ठीक बूल बी = नलप्टर; // ठीक है। ख झूठा है। int i = नलप्टर; // गलती
फू (नलप्टर); // कॉल फू (nullptr_t), फू नहीं (int); /*
ध्यान दें कि ऊपर दिए गए उदाहरण में foo(nullptr_t) वास्तव में foo(char *) को अंतर्निहित रूपांतरण का उपयोग करके कॉल करेगा, केवल तभी जब संगत पॉइंटर प्रकारों के दायरे में कोई अन्य फ़ंक्शन ओवरलोडिंग नहीं कर रहा हो। यदि एकाधिक ओवरलोडिंग सम्मिलित हैं, तो संकल्प विफल हो जाएगा क्योंकि यह अस्पष्ट है, जब तक कि फू (nullptr_t) की स्पष्ट घोषणा न हो।
सी ++ 11 के लिए मानक प्रकार के शीर्षलेखों में, nullptr_t प्रकार को इस प्रकार घोषित किया जाना चाहिए: टाइपपीफ डिक्लटाइप (नलप्टर) नलप्टर_टी; लेकिन नहीं के रूप में: टाइपपीफ int nullptr_t; // सी ++ के पूर्व संस्करण जिन्हें NULL को 0 के रूप में परिभाषित करने की आवश्यकता है टाइपपीफ शून्य *nullptr_t; // एएनएसआई सी जो न्यूल को ((शून्य *) 0) के रूप में परिभाषित करता है
- /
जोरदार ढंग से टाइप की गई गणनाएं
सी ++ 03 में, गणना टाइप-सुरक्षित नहीं हैं। गणना प्रकार अलग होने पर भी वे प्रभावी रूप से पूर्णांक होते हैं। यह विभिन्न गणना प्रकार के दो गणना मूल्यों के बीच तुलना की अनुमति देता है। सी ++ 03 प्रदान करने वाली एकमात्र सुरक्षा यह है कि एक पूर्णांक या एक एनम प्रकार का मान निहित रूप से किसी अन्य एनम प्रकार में परिवर्तित नहीं होता है। इसके अलावा, अंतर्निहित अभिन्न प्रकार कार्यान्वयन-परिभाषित है; कोड जो गणना के आकार पर निर्भर करता है, इस प्रकार गैर-पोर्टेबल है। अंत में, गणना मूल्यों को संलग्न दायरे में रखा गया है। इस प्रकार, एक ही दायरे में दो अलग-अलग गणनाओं के लिए मेल खाते सदस्य नाम होना संभव नहीं है।
C++11 गणना के एक विशेष वर्गीकरण की अनुमति देता है जिसमें इनमें से कोई भी समस्या नहीं है। इसका उपयोग करके व्यक्त किया जाता है enum class
(enum struct
पर्यायवाची के रूप में भी स्वीकार किया जाता है) घोषणा:
एनम वर्ग गणना {
Val1, Val2, वैल3 = 100, वैल4 // = 101
};
यह गणना प्रकार-सुरक्षित है। Enum वर्ग मान पूर्ण रूप से पूर्णांक में परिवर्तित नहीं होते हैं। इस प्रकार, उनकी तुलना पूर्णांकों से भी नहीं की जा सकती (अभिव्यक्ति Enumeration::Val4 == 101
संकलन त्रुटि देता है)।
अंतर्निहित प्रकार के एनम वर्ग हमेशा ज्ञात होते हैं। डिफ़ॉल्ट प्रकार है int
; इसे एक अलग अभिन्न प्रकार से ओवरराइड किया जा सकता है जैसा कि इस उदाहरण में देखा जा सकता है:
एनम वर्ग Enum2: अहस्ताक्षरित int {Val1, Val2};
पुरानी शैली की गणनाओं के साथ मूल्यों को बाहरी दायरे में रखा जाता है। नई शैली की गणनाओं के साथ उन्हें एनम वर्ग के नाम के दायरे में रखा गया है। तो उपरोक्त उदाहरण में, Val1
अपरिभाषित है, लेकिन Enum2::Val1
परिभाषित किया गया।
पुरानी शैली की गणनाओं को स्पष्ट स्कूपिंग प्रदान करने और अंतर्निहित प्रकार की परिभाषा प्रदान करने के लिए एक संक्रमणकालीन वाक्यविन्यास भी है:
एनम Enum3: अहस्ताक्षरित लंबा {Val1 = 1, Val2};
इस मामले में गणनाकर्ता के नाम गणना के दायरे में परिभाषित किए गए हैं (Enum3::Val1
), लेकिन पश्चगामी अनुकूलता के लिए उन्हें संलग्न दायरे में भी रखा गया है।
C++ 11 में फ़ॉरवर्ड-डिक्लेयरिंग एनम भी संभव है। पूर्व में, गणना के प्रकार आगे घोषित नहीं किए जा सकते थे क्योंकि गणना का आकार इसके सदस्यों की परिभाषा पर निर्भर करता है। जब तक गणना का आकार स्पष्ट रूप से या स्पष्ट रूप से निर्दिष्ट किया जाता है, तब तक इसे अग्रेषित घोषित किया जा सकता है:
एनम एनम 1; // सी ++ 03 और सी ++ 11 में अमान्य; अंतर्निहित प्रकार निर्धारित नहीं किया जा सकता है। एनम Enum2 : अहस्ताक्षरित int; // सी ++ 11 में मान्य, अंतर्निहित प्रकार स्पष्ट रूप से निर्दिष्ट है। एनम वर्ग Enum3; // सी ++ 11 में मान्य, अंतर्निहित प्रकार int है। एनम वर्ग Enum4 : अहस्ताक्षरित int; // सी ++ 11 में मान्य। एनम Enum2 : अहस्ताक्षरित छोटा; // C++11 में अमान्य, क्योंकि Enum2 को पहले एक अलग अंतर्निहित प्रकार के साथ घोषित किया गया था।
समकोण कोष्ठक
सी ++ 03 का पार्सर परिभाषित करता है ">>
” सभी मामलों में राइट शिफ्ट ऑपरेटर या स्ट्रीम एक्सट्रैक्शन ऑपरेटर के रूप में। चूंकि, नेस्टेड टेम्प्लेट घोषणाओं के साथ, प्रोग्रामर के लिए दो समकोण कोष्ठकों के बीच एक स्थान रखने की उपेक्षा करने की प्रवृत्ति होती है, इस प्रकार एक कंपाइलर सिंटैक्स त्रुटि होती है।
सी ++ 11 पार्सर के विनिर्देश में सुधार करता है जिससे कि कई समकोण कोष्ठकों को टेम्पलेट तर्क सूची को बंद करने के रूप में समझा जा सके जहां यह उचित है। पैरामीटर एक्सप्रेशन के चारों ओर कोष्ठक का उपयोग करके इसे ओवरराइड किया जा सकता है ">
”, “>=
" या ">>
"बाइनरी ऑपरेटर्स:
टेम्प्लेट <बूल टेस्ट> क्लास समटाइप; एसटीडी :: वेक्टर <कुछ टाइप <1> 2>> एक्स 1; // एक एसटीडी के रूप में व्याख्या :: SomeType <true> के वेक्टर,
// इसके बाद 2 >> X1 है, जो घोषणाकर्ता के लिए मान्य सिंटैक्स नहीं है। 1 सत्य है।
एसटीडी :: वेक्टर <कुछ टाइप <(1> 2) >> एक्स 1; // एसटीडी के रूप में व्याख्या :: कुछ प्रकार के वेक्टर <गलत>,
// इसके बाद डिक्लेरेटर x1 आता है, जो वैध C++11 सिंटैक्स है। (1>2) असत्य है।
स्पष्ट रूपांतरण ऑपरेटर
सी ++ 98 जोड़ा गया explicit
कीवर्ड को कंस्ट्रक्टर पर एक संशोधक के रूप में इस्तेमाल किया जा सकता है जिससे कि सिंगल-तर्क कंस्ट्रक्टर को अंतर्निहित प्रकार के रूपांतरण ऑपरेटर के रूप में उपयोग करने से रोका जा सके। चूंकि, यह वास्तविक रूपांतरण ऑपरेटरों के लिए कुछ नहीं करता है। उदाहरण के लिए, एक स्मार्ट पॉइंटर क्लास में a operator bool()
इसे एक आदिम सूचक की तरह अधिक कार्य करने की अनुमति देने के लिए: यदि इसमें यह रूपांतरण सम्मिलित है, तो इसका परीक्षण किया जा सकता है if (smart_ptr_variable)
(जो सच होगा यदि सूचक गैर-शून्य और अन्यथा झूठा था)। चूंकि, यह अन्य, अनपेक्षित रूपांतरणों को भी अनुमति देता है। क्योंकि सी ++ bool
एक अंकगणितीय प्रकार के रूप में परिभाषित किया गया है, इसे अंतर्निहित रूप से अभिन्न या फ़्लोटिंग-पॉइंट प्रकारों में परिवर्तित किया जा सकता है, जो गणितीय संचालन की अनुमति देता है जो उपयोगकर्ता द्वारा अभिप्रेत नहीं है।
सी ++ 11 में, explicit
कीवर्ड अब रूपांतरण ऑपरेटरों पर लागू किया जा सकता है। कन्स्ट्रक्टर के साथ, यह उन रूपांतरण कार्यों को अंतर्निहित रूपांतरणों में उपयोग करने से रोकता है। चूंकि, भाषा के संदर्भ जिन्हें विशेष रूप से एक बूलियन मान की आवश्यकता होती है (if-स्टेटमेंट और लूप की स्थिति, और तार्किक ऑपरेटरों के लिए संचालन) को स्पष्ट रूपांतरण के रूप में गिना जाता है और इस प्रकार एक बूल रूपांतरण ऑपरेटर का उपयोग कर सकता है।
उदाहरण के लिए, यह फीचर b:More C++ Idioms/Safe bool इश्यू को सफाई से हल करता है।
टेम्पलेट उपनाम
सी ++ 03 में, एक टाइपपीफ को केवल अन्य प्रकार के समानार्थी के रूप में परिभाषित करना संभव है, जिसमें निर्दिष्ट सभी वास्तविक टेम्पलेट तर्कों के साथ टेम्पलेट विशेषज्ञता के समानार्थी सम्मिलित हैं। टाइपपीफ टेम्पलेट बनाना संभव नहीं है। उदाहरण के लिए:
टेम्प्लेट <टाइपनेम फर्स्ट, टाइपनेम सेकेंड, इंट थर्ड>
वर्ग कुछ प्रकार;
टेम्पलेट <टाइपनाम दूसरा> टाइपपीफ कुछ प्रकार <अन्य प्रकार, दूसरा, 5> टाइपपीफनाम; // सी ++ 03 में अमान्य
यह संकलित नहीं होगा।
सी ++ 11 इस सिंटैक्स के साथ इस क्षमता को जोड़ता है:
टेम्प्लेट <टाइपनेम फर्स्ट, टाइपनेम सेकेंड, इंट थर्ड> वर्ग कुछ प्रकार;
टेम्पलेट <टाइपनाम दूसरा>
TypedefName = SomeType<OtherType, Second, 5>;
using
e> सिंटैक्स का उपयोग C++ 11 में टाइप अलियासिंग के रूप में भी किया जा सकता है:
टाइपपीफ शून्य (* फंक्शन टाइप) (डबल); // पुराना तरीका फंक्शनटाइप = शून्य (*) (डबल) का उपयोग करना; // नया पेश किया गया सिंटैक्स
अप्रतिबंधित संघ
सी ++ 03 में, किस प्रकार की वस्तुओं के सदस्य हो सकते हैं इस पर प्रतिबंध हैं union
. उदाहरण के लिए, यूनियनों में ऐसी कोई वस्तु नहीं हो सकती है जो गैर-तुच्छ कन्स्ट्रक्टर या विनाशक को परिभाषित करती है। C++11 इनमें से कुछ प्रतिबंधों को हटाता है।[3]
यदि एक union
सदस्य के पास एक गैर-तुच्छ विशेष सदस्य कार्य है, संकलक इसके लिए समकक्ष सदस्य फ़ंक्शन उत्पन्न नहीं करेगा union
और इसे मैन्युअल रूप से परिभाषित किया जाना चाहिए।
यह C++11 में अनुमत यूनियन का एक सरल उदाहरण है:
- सम्मिलित <नया> // नियुक्ति के लिए आवश्यक 'नया'।
संरचना बिंदु {
बिंदु() {} बिंदु (int x, int y): x_(x), y_(y) {} इंट x_, y_;
};
संघ यू {
इंट जेड; डबल डब्ल्यू; प्वाइंट पी; // सी ++ 03 में अमान्य; सी ++ 11 में मान्य। यू() {} // प्वाइंट सदस्य के कारण, अब एक कन्स्ट्रक्टर परिभाषा की आवश्यकता है। यू (स्थिरांक बिंदु और पीटी): पी (पीटी) {} // प्रारंभकर्ता सूची का उपयोग करके प्वाइंट ऑब्जेक्ट का निर्माण करें। यू एंड ऑपरेटर = (स्थिरांक प्वाइंट और पीटी) {नया (& पी) प्वाइंट (पीटी); वापसी * यह; } // प्लेसमेंट 'नया' का उपयोग करके पॉइंट ऑब्जेक्ट असाइन करें।
};
परिवर्तन किसी भी मौजूदा कोड को नहीं तोड़ेंगे क्योंकि वे केवल मौजूदा नियमों को शिथिल करते हैं।
कोर भाषा कार्यक्षमता में सुधार
ये विशेषताएं भाषा को उन चीजों को करने की अनुमति देती हैं जो पहले असंभव थीं, अत्यधिक वर्बोज़ थीं, या गैर-पोर्टेबल लाइब्रेरी की आवश्यकता थी।
वैराडिक टेम्प्लेट
सी ++ 11 में, टेम्पलेट टेम्पलेट पैरामीटर के परिवर्तनीय संख्या ले सकते हैं। यह प्रकार-सुरक्षित वैरिएडिक कार्यों की परिभाषा की भी अनुमति देता है।
नया स्ट्रिंग शाब्दिक
C++ 03 दो प्रकार के स्ट्रिंग लिटरल प्रदान करता है। डबल कोट्स के भीतर निहित पहली तरह, प्रकार की एक शून्य-समाप्त सरणी उत्पन्न करती है const char
. दूसरी तरह, के रूप में परिभाषित किया गया L""
, प्रकार की एक अशक्त-समाप्त सरणी उत्पन्न करता है const wchar_t
, कहाँ wchar_t
अपरिभाषित आकार और शब्दार्थ का एक विस्तृत-चरित्र है। कोई भी शाब्दिक प्रकार UTF-8, UTF-16, या यूनिकोड एन्कोडिंग की किसी अन्य प्रकार की यूनिकोड तुलना के साथ स्ट्रिंग शाब्दिक के लिए समर्थन प्रदान नहीं करता है।
C++11 तीन यूनिकोड एनकोडिंग का समर्थन करता है: UTF-8, UTF-16 और UTF-32। प्रकार की परिभाषा char
स्पष्ट रूप से व्यक्त करने के लिए संशोधित किया गया है कि यह कम से कम UTF-8 के आठ-बिट कोडिंग को संग्रहीत करने के लिए आवश्यक आकार है, और संकलक के मूल निष्पादन वर्ण सेट के किसी भी सदस्य को सम्मिलित करने के लिए पर्याप्त बड़ा है। इसे पूर्व में सी ++ मानक में केवल बाद वाले के रूप में परिभाषित किया गया था, फिर कम से कम 8 बिट्स की गारंटी के लिए सी मानक पर निर्भर था। इसके अलावा, सी ++ 11 दो नए चरित्र प्रकार जोड़ता है: char16_t
और char32_t
. ये क्रमशः UTF-16 और UTF-32 को स्टोर करने के लिए डिज़ाइन किए गए हैं।
प्रत्येक समर्थित एनकोडिंग के लिए स्ट्रिंग शाब्दिक बनाना इस प्रकार किया जा सकता है:
u8 मैं एक UTF-8 स्ट्रिंग हूँ। u यह एक UTF-16 स्ट्रिंग है। U यह एक UTF-32 स्ट्रिंग है।
पहली स्ट्रिंग का प्रकार सामान्य है const char[]
. दूसरी कड़ी का प्रकार है const char16_t[]
(नोट लोअर केस 'यू' उपसर्ग)। तीसरे तार का प्रकार है const char32_t[]
(अपर केस 'यू' उपसर्ग)।
यूनिकोड स्ट्रिंग शाब्दिक का निर्माण करते समय, यूनिकोड कोड बिंदुओं को सीधे स्ट्रिंग में सम्मिलित करना अक्सर उपयोगी होता है। ऐसा करने के लिए, C++11 इस सिंटैक्स की अनुमति देता है:
u8 यह एक यूनिकोड कैरेक्टर है: \u2018। u यह एक बड़ा यूनिकोड कैरेक्टर है: \u2018। यू यह एक यूनिकोड वर्ण है: \U00002018।
के बाद की संख्या \u
एक हेक्साडेसिमल संख्या है; इसे सामान्य की आवश्यकता नहीं है 0x
उपसर्ग। पहचानकर्ता \u
16-बिट यूनिकोड कोड बिंदु का प्रतिनिधित्व करता है; 32-बिट कोड बिंदु दर्ज करने के लिए, उपयोग करें \U
और एक 32-बिट हेक्साडेसिमल संख्या। केवल मान्य यूनिकोड कोड अंक दर्ज किए जा सकते हैं। उदाहरण के लिए, U+D800–U+DFFF श्रेणी पर कोड बिंदु निषिद्ध हैं, क्योंकि वे UTF-16 एन्कोडिंग में सरोगेट जोड़े के लिए आरक्षित हैं।
यह कभी-कभी मैन्युअल रूप से स्ट्रिंग्स से बचने के लिए उपयोगी होता है, विशेष रूप से एक्सएमएल फाइलों, स्क्रिप्टिंग भाषाओं या नियमित अभिव्यक्तियों के अक्षर का उपयोग करने के लिए। सी ++ 11 एक कच्ची स्ट्रिंग शाब्दिक प्रदान करता है:
R (स्ट्रिंग डेटा \ Stuff ) आर सीमांकक (स्ट्रिंग डेटा \ सामग्री) सीमांकक </पूर्व> पहली स्थिति में, के बीच सब कुछ"(
और यह)"
कड़ी का हिस्सा है।"
ई> और\
पात्रों को भागने की जरूरत नहीं है। दूसरे मामले में,"delimiter(
स्ट्रिंग शुरू करता है, और यह तभी समाप्त होता है जब)delimiter"
पहुंच गया। डोरdelimiter
रिक्त स्ट्रिंग सहित लंबाई में 16 वर्णों तक कोई भी स्ट्रिंग हो सकती है। इस स्ट्रिंग में रिक्त स्थान, नियंत्रण वर्ण नहीं हो सकते,(
,)
, या\
चरित्र। इस सीमांकक स्ट्रिंग का उपयोग करके, उपयोगकर्ता के पास हो सकता है)
कच्चे स्ट्रिंग शाब्दिक के भीतर वर्ण। उदाहरण के लिए,R"delimiter((a-z))delimiter"
के बराबर है"(a-z)"
.[4] रॉ स्ट्रिंग लिटरल को वाइड लिटरल या यूनिकोड लिटरल प्रीफिक्स में से किसी के साथ जोड़ा जा सकता है:
- ↑ "We have an international standard: C++0x is unanimously approved". 12 August 2011. Archived from the original on 11 December 2018. Retrieved 12 August 2011.
- ↑ Stroustrup, Bjarne. "C++11 FAQ". stroustrup.com. Archived from the original on 2018-10-06. Retrieved 2014-10-15.
- ↑ "C++11 Overview: What specific design goals guided the committee?". Standard C++. Archived from the original on 2019-01-31. Retrieved 2015-09-04.
- ↑ "Bjarne Stroustrup: A C++0x overview" (PDF). Archived (PDF) from the original on 17 June 2016. Retrieved 30 June 2011.
- ↑ "ISO/IEC 14882:2011". ISO. 2 September 2011. Archived from the original on 29 January 2013. Retrieved 3 September 2011.
- ↑ "Working Draft, Standard for Programming Language C++" (PDF). Archived (PDF) from the original on 2019-01-21. Retrieved 2012-04-26.
- ↑ "The Standard". Archived from the original on 2019-05-13. Retrieved 2012-11-02.
- ↑ सटर, अलेक्जेंड्रेस्कु C++ कोडिंग मानक #15
- ↑ Gabriel Dos Reis; Bjarne Stroustrup (22 March 2010). "General Constant Expressions for System Programming Languages, Proceedings SAC '10" (PDF). Archived (PDF) from the original on 13 June 2018. Retrieved 18 August 2012.
- ↑ Jaakko Järvi; Bjarne Stroustrup; Douglas Gregor; Jeremy Siek (April 28, 2003). "Decltype and auto, Programming Language C++, Document no: N1478=03-0061" (PDF). Archived (PDF) from the original on May 28, 2015. Retrieved June 6, 2015.
- ↑ Roger Orr (June 2013). ""Auto – A Necessary Evil?" Overload Journal #115". Archived from the original on 2015-06-06. Retrieved 2015-06-06.
- ↑ "Document no: N1968=06-0038- Lambda expressions and closures for C++" (PDF). Open Standards. Archived (PDF) from the original on 2011-07-28. Retrieved 2009-04-20.
- ↑ "Decltype (revision 5)" (PDF). Archived (PDF) from the original on 2022-02-14. Retrieved 2022-02-16.
- ↑ "auto specifier (since C++11) - cppreference.com". en.cppreference.com. Archived from the original on 2016-10-20. Retrieved 2016-10-18.
- ↑ Gustedt, Jens (2019-07-09). "Introduce the nullptr constant - v1" (PDF). ISO JTC1/SC22/WG14 Document Register. International Organization for Standardization. Archived (PDF) from the original on 2020-07-27. Retrieved 2020-04-19 – via open-std.org.