c++ - मैं कक्षा में गैर-स्थिर स्थिर सदस्य या स्थैतिक सरणी क्यों शुरू नहीं कर सकता?




static const (3)

मैं कक्षा में static डेटा सदस्यों को क्यों शुरू नहीं कर सकता?

सी ++ मानक कक्षा के अंदर केवल स्थिर स्थिर अभिन्न या गणना प्रकारों को आरंभ करने की अनुमति देता है। यही कारण a कि प्रारंभ करने की अनुमति है जबकि अन्य नहीं हैं।

संदर्भ:
सी ++ 03 9.4.2 स्टेटिक डेटा सदस्य
§4

यदि एक स्थिर डेटा सदस्य कॉन्स अभिन्न या कॉन्स्ट गणना प्रकार का है, तो कक्षा परिभाषा में इसकी घोषणा एक स्थिर-प्रारंभकर्ता निर्दिष्ट कर सकती है जो एक अभिन्न निरंतर अभिव्यक्ति (5.1 9) होगी। उस स्थिति में, सदस्य अभिन्न निरंतर अभिव्यक्तियों में प्रकट हो सकता है। सदस्य को अभी भी नामस्थान स्कोप में परिभाषित किया जाएगा यदि इसका उपयोग प्रोग्राम में किया जाता है और नामस्थान स्कोप परिभाषा में प्रारंभकर्ता नहीं होना चाहिए।

अभिन्न प्रकार क्या हैं?

सी ++ 03 3.9.1 मौलिक प्रकार
§7

प्रकार बूल, चार, wchar_t, और हस्ताक्षरित और हस्ताक्षरित पूर्णांक प्रकार सामूहिक रूप से अभिन्न प्रकार कहा जाता है .3) अभिन्न प्रकार के लिए समानार्थी पूर्णांक प्रकार है।

पाद लेख:

43) इसलिए, गणना (7.2) अभिन्न नहीं हैं; हालांकि, 4.5 में निर्दिष्ट अनुसार, गणनाओं को int, unsigned int, long, या unsigned long तक प्रचारित किया जा सकता है।

युक्ति:

आप अपनी कक्षा परिभाषा के अंदर एक सरणी शुरू करने के लिए enum चाल का उपयोग कर सकते हैं।

class A 
{
    static const int a = 3;
    enum { arrsize = 2 };

    static const int c[arrsize] = { 1, 2 };

};

मानक इसकी अनुमति क्यों नहीं देता है?

बजेर्ने ने यह उचित रूप से here :

एक वर्ग को आमतौर पर हेडर फ़ाइल में घोषित किया जाता है और एक हेडर फ़ाइल आमतौर पर कई अनुवाद इकाइयों में शामिल होती है। हालांकि, जटिल लिंकर नियमों से बचने के लिए, सी ++ की आवश्यकता है कि प्रत्येक ऑब्जेक्ट की एक अनूठी परिभाषा हो। उस नियम को तोड़ा जाएगा यदि सी ++ ने उन इकाइयों की कक्षा परिभाषा की अनुमति दी है जिन्हें वस्तुओं में वस्तुओं के रूप में संग्रहीत करने की आवश्यकता होती है।

इन-क्लास प्रारंभिक अनुमति केवल static const अभिन्न प्रकार और enums क्यों हैं?

बजरने के उद्धरण में इसका जवाब छिपा हुआ है, इसे बारीकी से पढ़ें,
"सी ++ की आवश्यकता है कि प्रत्येक ऑब्जेक्ट में एक अनूठी परिभाषा हो। वह नियम तोड़ा जाएगा यदि सी ++ ने उन इकाइयों की कक्षा परिभाषा की अनुमति दी है जिन्हें वस्तुओं में वस्तुओं के रूप में संग्रहीत करने की आवश्यकता होती है।"

ध्यान दें कि केवल static const पूर्णांक को संकलन समय स्थिरांक के रूप में माना जा सकता है। कंपाइलर जानता है कि पूर्णांक मान कभी भी नहीं बदलेगा और इसलिए यह अपने स्वयं के जादू को लागू कर सकता है और अनुकूलन लागू कर सकता है, संकलक बस ऐसे वर्ग के सदस्यों को रेखांकित करता है यानी, वे अब स्मृति में संग्रहीत नहीं हैं, क्योंकि स्मृति में संग्रहीत होने की आवश्यकता को हटा दिया जाता है , यह बजेर्ने द्वारा वर्णित नियम के अपवाद को ऐसे चर देता है।

यहां ध्यान देने योग्य है कि यहां तक ​​कि यदि static const अभिन्न मूल्यों में इन-क्लास प्रारंभिक हो सकता है, तो ऐसे चर के पते को लेने की अनुमति नहीं है। कोई एक स्थिर सदस्य का पता ले सकता है यदि (और केवल अगर) इसमें कक्षा से बाहर की परिभाषा है। यह आगे तर्क को मान्य करता है।

enums की अनुमति है क्योंकि एक गणना प्रकार के मूल्यों का उपयोग किया जा सकता है जहां चींटियों की उम्मीद है। उपरोक्त उद्धरण देखें

सी ++ 11 में यह कैसे बदलता है?

सी ++ 11 कुछ हद तक प्रतिबंध को आराम देता है।

सी ++ 11 9.4.2 स्टेटिक डेटा सदस्य
§3

यदि एक स्थैतिक डेटा सदस्य कॉन्स शाब्दिक प्रकार का है, तो कक्षा परिभाषा में इसकी घोषणा एक ब्रेस-या-बराबर-प्रारंभकर्ता निर्दिष्ट कर सकती है जिसमें प्रत्येक प्रारंभकर्ता-खंड जो असाइनमेंट-अभिव्यक्ति है, निरंतर अभिव्यक्ति है। शाब्दिक प्रकार के एक स्थिर डेटा सदस्य को क्लास परिभाषा में constexpr specifier; साथ घोषित किया जा सकता है constexpr specifier; यदि हां, तो इसकी घोषणा एक ब्रेस-या-बराबर-प्रारंभकर्ता निर्दिष्ट करेगी जिसमें प्रत्येक प्रारंभकर्ता-खंड जो एक असाइनमेंट-अभिव्यक्ति है, निरंतर अभिव्यक्ति है। [नोट: इन दोनों मामलों में, सदस्य निरंतर अभिव्यक्तियों में दिखाई दे सकता है। -जेंड नोट] सदस्य को अभी भी नामस्थान स्कोप में परिभाषित किया जाएगा यदि इसका उपयोग प्रोग्राम में किया जाता है और नामस्थान स्कोप परिभाषा में प्रारंभकर्ता नहीं होना चाहिए।

इसके अलावा, सी ++ 11 (§12.6.2.8) को गैर-स्थैतिक डेटा सदस्य को प्रारंभ करने के लिए अनुमति देगा जहां इसे घोषित किया जाता है (इसकी कक्षा में)। इसका मतलब बहुत आसान उपयोगकर्ता अर्थशास्त्र होगा।

ध्यान दें कि इन सुविधाओं को अभी तक नवीनतम जीसीसी 4.7 में लागू नहीं किया गया है, इसलिए आपको अभी भी संकलन त्रुटियां मिल सकती हैं।

मैं कक्षा में गैर- static सदस्य या static सरणी क्यों शुरू नहीं कर सकता?

class A
{
    static const int a = 3;
    static int b = 3;
    static const int c[2] = { 1, 2 };
    static int d[2] = { 1, 2 };
};

int main()
{
    A a;

    return 0;
}

त्रुटियों के बाद संकलक समस्याएं:

g++ main.cpp
main.cpp:4:17: error: ISO C++ forbids in-class initialization of non-const static member ‘b’
main.cpp:5:26: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:5:33: error: invalid in-class initialization of static data member of non-integral type ‘const int [2]’
main.cpp:6:20: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:6:27: error: invalid in-class initialization of static data member of non-integral type ‘int [2]’

मेरे पास दो प्रश्न हैं:

  1. मैं कक्षा में static डेटा सदस्यों को क्यों शुरू नहीं कर सकता?
  2. मैं कक्षा में static सरणी, यहां तक ​​कि const सरणी क्यों शुरू नहीं कर सकता?

मुझे लगता है कि यह आपको घोषणाओं और परिभाषाओं को मिश्रण करने से रोकने के लिए है। (यदि आप एकाधिक स्थानों में फ़ाइल शामिल करते हैं तो उन समस्याओं के बारे में सोचें जो हो सकती हैं।)


स्थिर चर एक वर्ग के लिए विशिष्ट हैं। रचनाकार एक उदाहरण के लिए विशेषताओं को विशेष रूप से प्रारंभ करते हैं।





const