दिलचस्प पोस्ट
एंड्रॉइड एसडीके: इसे प्रदर्शित किए बिना कच्चे पूर्वावलोकन कैमरा छवि प्राप्त करें दृश्य मॉडल (सी #) से WPF में पाठ बॉक्स पर फ़ोकस सेट करें क्यों कंस्ट्रक्टरों को जावा में विरासत में नहीं लिया जा सकता है? ट्विटर बूटस्ट्रैप 3, खड़ी केंद्र सामग्री setValue: forUndefinedKey: यह वर्ग कुंजी के लिए मूल्य मान कोडन-अनुरूप नहीं है सी में एक परिपत्र बफर को कैसे लागू करें? बहुआयामी arrays के साथ array_diff () अजगर का समय कितना सही है? ()? एकाधिक कॉलम एक साथ पेस्ट करें शेल कमांड को प्रत्येक आउटपुट के आदेश आउटपुट में कैसे लागू करें? जावा में प्रतिलिपि कन्स्ट्रक्टर का निर्माण करना डेटाबेस इंडेक्स बनाने के लिए कुछ सर्वोत्तम प्रथाओं और "अंगूठे के नियम" क्या हैं? रनटाइम / चेक / अनचेक / त्रुटि / अपवाद के बीच अंतर getSupportFragmentManager ()। getFragments () एक संकलन समय त्रुटि दिखाता है छवि-नक्शे और छवियों को गतिशील रूप से रीसाइज़ करना

सी ++ स्थिर स्थिर स्ट्रिंग (कक्षा सदस्य)

मैं एक वर्ग के लिए एक निजी स्थिर स्थिर रखना चाहता हूं (इस मामले में एक आकार-कारखाना)। मुझे इस तरह के बारे में कुछ करना है

class A { private: static const string RECTANGLE = "rectangle"; } 

दुर्भाग्य से मुझे C ++ (g ++) कंपाइलर से सभी प्रकार की त्रुटि मिलती है, जैसे कि:

आईएसओ सी ++ सदस्य 'RECTANGLE' के आरम्भिकरण को रोकता है

गैर-इंटीग्रल प्रकार 'std :: string' के स्थिर डेटा सदस्य के अवैध इन-क्लास आरंभीकरण

त्रुटि: 'RECTANGLE' स्थिर बना रहा है

यह मुझसे कहता है कि इस तरह की सदस्य डिजाइन मानक के अनुरूप नहीं है # डीफ़ाईन डायरेक्टिव के उपयोग के बिना आपके पास एक निजी शाब्दिक स्थिर (या शायद सार्वजनिक) कैसे है (मैं डेटा ग्लैबिलिटी की बदसूरत से बचना चाहता हूं!)

किसी भी मदद की सराहना की है धन्यवाद।

Solutions Collecting From Web of "सी ++ स्थिर स्थिर स्ट्रिंग (कक्षा सदस्य)"

आपको अपने स्थिर सदस्य को कक्षा की परिभाषा के बाहर परिभाषित करना होगा और वहां प्रारंभकर्ता को प्रदान करना होगा।

प्रथम

 // In a header file (if it is in a header file in your case) class A { private: static const string RECTANGLE; }; 

और फिर

 // In one of the implementation files const string A::RECTANGLE = "rectangle"; 

वाक्यविन्यास जो आप मूल रूप से उपयोग करने की कोशिश कर रहे थे (कक्षा परिभाषा के अंदर initializer) केवल अभिन्न और enum प्रकारों के साथ अनुमति दी जाती है।

सी ++ 11 में आप अब कर सकते हैं:

 class A { private: static constexpr const char* STRING = "some useful string constant"; }; 

क्लास की परिभाषाओं के अंदर आप केवल स्थिर सदस्य घोषित कर सकते हैं। उन्हें कक्षा के बाहर परिभाषित करना होगा संकलन-समय अभिन्न स्थिरांक के लिए मानक अपवाद बनाता है कि आप सदस्यों को "आरंभ" कर सकते हैं यह अभी भी एक परिभाषा नहीं है, यद्यपि। इस पते को लेना बिना परिभाषा के काम नहीं करेगा, उदाहरण के लिए

मैं यह उल्लेख करना चाहूंगा कि मुझे स्थिरांक के लिए std :: स्ट्रिंग का उपयोग करने के लाभ को स्थिरांक नहीं मिल रहा है [] std :: string अच्छा है और सभी लेकिन इसके लिए गतिशील प्रारंभिक आवश्यकता है। तो, अगर आप कुछ ऐसा लिखते हैं

 const std::string foo = "hello"; 

नेमस्पेस गुंजाइश पर फ़ू के कन्स्ट्रक्टर को मुख्य आरंभ के निष्पादन से पहले ठीक किया जाएगा और यह कन्स्ट्रक्टर हीप मेमोरी में निरंतर "हैलो" की एक प्रतिलिपि बनाएगा। जब तक आपको वास्तव में एक STD :: स्ट्रिंग के लिए RECTANGLE की आवश्यकता होती है, तब तक आप लिख सकते हैं

 // class definition with incomplete static member could be in a header file class A { static const char RECTANGLE[]; }; // this needs to be placed in a single translation unit only const char A::RECTANGLE[] = "rectangle"; 

क्या आप वहां मौजूद हैं! कोई ढेर आवंटन, कोई प्रतिलिपि नहीं, कोई गतिशील प्रारंभ नहीं।

चीयर्स, एस

यह सिर्फ अतिरिक्त सूचना है, लेकिन यदि आप वाकई हेडर फ़ाइल में स्ट्रिंग चाहते हैं, तो कुछ ऐसा प्रयास करें:

 class foo { public: static const std::string& RECTANGLE(void) { static const std::string str = "rectangle"; return str; } }; 

हालांकि मुझे संदेह है कि इसकी सिफारिश की गई है।

उस क्लास इनिशियलाइज़ेशन सिंटैक्स का उपयोग करने के लिए, स्थिरांक एक स्थिर अभिव्यक्ति द्वारा इंटीग्रल या एन्यूमरेशन प्रकार के प्रारंभिक प्रकार का होना चाहिए।

यह प्रतिबंध है इसलिए, इस मामले में आपको कक्षा के बाहर चर को परिभाषित करने की आवश्यकता होती है। @ एंड्री टी से जवाबवाले देखें

संभव है कि बस करो:

 static const std::string RECTANGLE() const { return "rectangle"; } 

या

 #define RECTANGLE "rectangle" 

वर्तमान मानक केवल स्थिर निरंतर अभिन्न प्रकारों के लिए इस तरह के आरंभीकरण की अनुमति देता है। तो आपको एंड्री की व्याख्या करने की आवश्यकता है हालांकि, यह नए सदस्य आरंभीकरण वाक्यविन्यास के माध्यम से अगले मानक में उपलब्ध होगा।

आप या तो ऊपर वर्णित const char* समाधान के लिए जा सकते हैं, लेकिन फिर अगर आपको हर समय स्ट्रिंग की आवश्यकता होती है, तो आप बहुत ज्यादा ओवरहेड होने जा रहे हैं
दूसरी तरफ, स्थैतिक स्ट्रिंग को डायनामिक आरंभीकरण की आवश्यकता होती है, इस प्रकार यदि आप किसी अन्य वैश्विक / स्थिर वैरिएबल के आरंभ के दौरान इसके मान का उपयोग करना चाहते हैं, तो आप इनिशियलाइज़ेशन ऑर्डर की समस्या को प्रभावित कर सकते हैं। उस से बचने के लिए, सबसे सस्ता चीज एक लास्टेटर के माध्यम से स्थिर स्ट्रिंग ऑब्जेक्ट तक पहुंच रहा है, जो यह जांचता है कि क्या आपका ऑब्जेक्ट आरंभीकृत है या नहीं।

 //in a header class A{ static string s; public: static string getS(); }; //in implementation string A::s; namespace{ bool init_A_s(){ A::s = string("foo"); return true; } bool A_s_initialized = init_A_s(); } string A::getS(){ if (!A_s_initialized) A_s_initialized = init_A_s(); return s; } 

केवल A::getS() उपयोग करने के लिए याद रखें चूंकि किसी भी थ्रेडिंग को केवल main() द्वारा शुरू किया जा सकता है, और A_s_initialized main() से पहले A_s_initialized जाता है, आपको बहुस्तरीय वातावरण में भी ताले की आवश्यकता नहीं है A_s_initialized 0 डिफ़ॉल्ट रूप से (गतिशील आरंभीकरण से पहले) है, इसलिए यदि आप आरंभ होने से पहले getS() उपयोग करते हैं, तो आप init फ़ंक्शन को सुरक्षित रूप से कॉल करते हैं

बीटीडब्ल्यू, ऊपर दिए गए उत्तर में: " स्थिर कॉन्स्ट std :: string RECTANGLE () const ", स्थैतिक फ़ंक्शन को const नहीं किया जा सकता क्योंकि वे किसी भी ऑब्जेक्ट को वैसे भी बदल नहीं सकते हैं (कोई भी सूचक नहीं है)।

वर्ग स्थिर चर को शीर्ष पर घोषित किया जा सकता है, लेकिन .cpp फाइल में परिभाषित किया जाना चाहिए। इसका कारण यह है कि स्थिर वैरिएबल का केवल एक उदाहरण हो सकता है और कंपाइलर तय नहीं कर सकता है कि उसमें जनरेटेड ऑब्जेक्ट फ़ाइल को क्यों रखा जाए ताकि आप को फैसला करना पड़े, बजाय

सी ++ 11 में घोषित होने के साथ एक स्थैतिक मूल्य की परिभाषा को रखने के लिए नेस्टेड स्थैतिक संरचना का इस्तेमाल किया जा सकता है। इस मामले में स्थिर सदस्य एक संरचना है और उसे। सीपीपी फ़ाइल में परिभाषित किया जाना चाहिए, लेकिन मान हेडर में हैं।

 class A { private: static struct _Shapes { const std::string RECTANGLE {"rectangle"}; const std::string CIRCLE {"circle"}; } shape; }; 

व्यक्तिगत सदस्यों को प्रारंभ करने के बजाय पूरी स्थिर संरचना को। सीपीपी में आरंभ किया गया है:

 A::_Shapes A::shape; 

मूल्यों के साथ प्रवेश किया जाता है

 A::shape.RECTANGLE; 

या – चूंकि सदस्य निजी होते हैं और इसका इस्तेमाल केवल ए के साथ ही किया जाता है

 shape.RECTANGLE; 

ध्यान दें कि यह समाधान अभी भी स्थैतिक चर के आरंभीकरण के क्रम की समस्या से ग्रस्त है। जब एक स्थिर वैल्यू अन्य स्थिर वैरिएबल को इनिशियलाइज़ करने के लिए प्रयोग किया जाता है, तो पहले आरंभ नहीं किया जा सकता है, फिर भी।

 // file.h class File { public: static struct _Extensions { const std::string h{ ".h" }; const std::string hpp{ ".hpp" }; const std::string c{ ".c" }; const std::string cpp{ ".cpp" }; } extension; }; // file.cpp File::_Extensions File::extension; // module.cpp static std::set<std::string> headers{ File::extension.h, File::extension.hpp }; 

इस मामले में स्थिर चर हेडर में या तो {""} या {".h", ".hpp"} शामिल होंगे, लिंकर द्वारा बनाए गए प्रारंभिकरण के आदेश के आधार पर।

जैसा कि @ ऐबिस .7 द्वारा उल्लिखित किया गया है, आप भी संकुचित रूप से उपयोग कर सकते हैं यदि चर का मान संकलन समय पर गणना किया जा सकता है। लेकिन यदि आप अपने स्ट्रिंग को static constexpr const char* साथ घोषित करते हैं और आपका प्रोग्राम std::string का उपयोग करता है अन्यथा वहाँ एक ओवरहेड होगा क्योंकि एक नई std::string ऑब्जेक्ट हर बार जब आप इस तरह के स्थिर उपयोग करते हैं, तब बनाया जाएगा:

 class A { public: static constexpr const char* STRING = "some value"; }; void foo(const std::string& bar); int main() { foo(A::STRING); // a new std::string is constructed and destroyed. }