मैं staticकक्षा में डेटा सदस्यों को प्रारंभिक क्यों नहीं कर सकता ?
C ++ मानक केवल स्थिर स्थिर अभिन्न या गणना प्रकार को वर्ग के अंदर आरंभ करने की अनुमति देता है। यही कारण aहै कि इनिशियलाइज़ होने की अनुमति है जबकि अन्य नहीं हैं।
संदर्भ:
C ++ 03
9.4.2 स्टेटिक डेटा सदस्य 9.44
यदि एक स्थैतिक डेटा सदस्य कास्ट इंटीग्रल या कास्ट एन्यूमरेशन प्रकार का होता है, तो क्लास डेफिनेशन में इसकी घोषणा एक निरंतर-प्रारंभक को निर्दिष्ट कर सकती है जो एक अभिन्न स्थिर अभिव्यक्ति (5.19) होगी। उस मामले में, सदस्य अभिन्न निरंतर अभिव्यक्तियों में प्रकट हो सकता है। यदि प्रोग्राम में उपयोग किया जाता है तो सदस्य को अभी भी नाम स्थान के दायरे में परिभाषित किया जाएगा और नाम स्थान की परिभाषा में इनिशियलाइज़र नहीं होगा।
अभिन्न प्रकार क्या हैं?
C ++ 03 3.9.1 मौलिक प्रकार
Fund7
प्रकार बूल, चार, wchar_t, और हस्ताक्षरित और अहस्ताक्षरित पूर्णांक प्रकार को सामूहिक रूप से अभिन्न प्रकार कहा जाता है। 4) अभिन्न प्रकार का एक पर्याय पूर्णांक प्रकार है।
पाद लेख:
43) इसलिए, गणना (7.2) अभिन्न नहीं हैं; हालाँकि, गणन को बढ़ावा दिया जा सकता है int, अहस्ताक्षरित int, लंबा या अहस्ताक्षरित, जैसा कि 4.5 में निर्दिष्ट है।
युक्ति:
आप अपनी कक्षा परिभाषा के अंदर एक सरणी को इनिशियलाइज़ करने के लिए एनम ट्रिक का उपयोग कर सकते हैं ।
class A
{
static const int a = 3;
enum { arrsize = 2 };
static const int c[arrsize] = { 1, 2 };
};
मानक यह अनुमति क्यों नहीं देता है?
बज्ने ने इसे यहाँ स्पष्ट रूप से समझाया है :
हेडर फ़ाइल में आमतौर पर एक वर्ग घोषित किया जाता है और हेडर फ़ाइल को आमतौर पर कई अनुवाद इकाइयों में शामिल किया जाता है। हालांकि, जटिल लिंकर नियमों से बचने के लिए, C ++ के लिए आवश्यक है कि प्रत्येक ऑब्जेक्ट की एक अनूठी परिभाषा हो। उस नियम को तोड़ा जाएगा, यदि C ++ को उन संस्थाओं की इन-क्लास परिभाषा की अनुमति दी जाए, जिन्हें वस्तुओं के रूप में मेमोरी में संग्रहीत करने की आवश्यकता होती है।
केवल static constअभिन्न प्रकार और एनमों को इन-क्लास इनिशियलाइज़ेशन की अनुमति क्यों है ?
उत्तर छिपा हुआ है बज्ने के उद्धरण में इसे बारीकी से पढ़ा गया है,
"सी ++ के लिए आवश्यक है कि प्रत्येक वस्तु की एक अनूठी परिभाषा हो। यदि नियम ++ को उन संस्थाओं की वर्गीय परिभाषा की अनुमति दी जाए जिन्हें स्मृति में वस्तुओं के रूप में संग्रहीत करने की आवश्यकता होती है।"
ध्यान दें कि केवल static constपूर्णांकों को संकलित समय स्थिरांक के रूप में माना जा सकता है। कंपाइलर जानता है कि पूर्णांक मान कभी भी नहीं बदलेगा और इसलिए यह अपना जादू चला सकता है और अनुकूलन को लागू कर सकता है, कंपाइलर ऐसे वर्ग के सदस्यों को केवल इनलाइन करता है यानी वे अब मेमोरी में संग्रहीत नहीं होते हैं, क्योंकि मेमोरी में संग्रहीत होने की आवश्यकता को हटा दिया जाता है। , यह ऐसे चर को बज़्ने द्वारा उल्लिखित नियम को अपवाद देता है।
यहाँ यह ध्यान देने योग्य है कि यदि static constअभिन्न मूल्यों में इन-क्लास इनिशियलाइज़ेशन हो सकता है, तो भी ऐसे चरों का पता लगाने की अनुमति नहीं है। एक स्थैतिक सदस्य का पता ले सकता है यदि (और केवल अगर) तो इसकी एक आउट-ऑफ-क्लास परिभाषा है। यह ऊपर दिए गए कारणों को मान्य करता है।
एनमों को इसकी अनुमति है क्योंकि एन्यूमरेटेड प्रकार के मूल्यों का उपयोग उन जगहों पर किया जा सकता है जहां इन्ट्स अपेक्षित हैं। ऊपर उद्धरण देखें
यह C ++ 11 में कैसे बदलता है?
सी ++ 11 कुछ हद तक प्रतिबंध को शांत करता है।
C ++ 11 9.4.2 स्टेटिक डेटा सदस्य
113
यदि एक स्थैतिक डेटा सदस्य कास्ट शाब्दिक प्रकार का है, तो क्लास डेफिनेशन में इसकी घोषणा एक ब्रेस-या-इक्विल-इनिशलाइज़र निर्दिष्ट कर सकती है जिसमें प्रत्येक इनिशियलाइज़र-क्लॉज जो एक असाइनमेंट-एक्सप्रेशन है, एक स्थिर अभिव्यक्ति है। शाब्दिक प्रकार का एक स्थैतिक डेटा सदस्य वर्ग परिभाषा में घोषित किया जा सकता है constexpr specifier;यदि ऐसा है, तो इसकी घोषणा एक ब्रेस-या-समतुल्य-आरंभक निर्दिष्ट करेगी जिसमें प्रत्येक आरंभिक-खंड जो एक असाइनमेंट-एक्सप्रेशन हैएक निरंतर अभिव्यक्ति है। [नोट: इन दोनों मामलों में, सदस्य निरंतर अभिव्यक्तियों में दिखाई दे सकता है। -एंड नोट] सदस्य को अभी भी नाम स्थान के दायरे में परिभाषित किया जाएगा यदि यह प्रोग्राम में उपयोग किया जाता है और नेमस्पेस गुंजाइश परिभाषा में इनिशियलाइज़र नहीं होगा।
इसके अलावा, सी ++ 11 जाएगा अनुमति देते हैं (§12.6.2.8) एक गैर स्थिर डेटा सदस्य जहां यह घोषित किया जाता है प्रारंभ (इसके मुक़दमे में)। यह बहुत आसान उपयोगकर्ता शब्दार्थ का मतलब होगा।
ध्यान दें कि इन सुविधाओं को अभी तक नवीनतम gcc 4.7 में लागू नहीं किया गया है, इसलिए आपको अभी भी संकलन त्रुटियां मिल सकती हैं।