2016-01-17 3 views
9

मुझे समझ में नहीं आता क्यों सी ++ कक्षा घोषणा के भीतर परिभाषित करने के लिए केवल अभिन्न प्रकार और enum (enum एक अभिन्न प्रकार भी) की अनुमति देता है। जबकि फ्लोट प्वाइंट प्रकार (यानी डबल और फ्लोट) समेत अन्य सभी प्रकारों को कक्षा घोषणा के बाहर परिभाषित किया जाना है। स्पष्ट रूप से इसके लिए एक कारण होना चाहिए, लेकिन मैं इसे समझ नहीं सकता।सी ++ कक्षा में केवल अभिन्न या enum प्रकार क्यों शुरू किया जा सकता है?

कोड उदाहरण:

#include <iostream> 

using namespace std; 

struct Node { 

    static const int c = 0; // Legal Definition 
    static const long l = 0l; // Legal Definition 
    static const short s = 0; // Legal Definition 

    static const float f = 0.0f; // Illegal definition 
    static const string S = "Test"; // Illegal definition 

    static const string JOB_TYPE; // Legal declaration 
    static const float f; // Legal declaration 
    static const double d; // Legal declaration 
}; 

const string Node::JOB_TYPE = "Test"; // correct definition 
const float Node::f = 0.0f; // correct definition 
const double Node::d = 0.0; // correct definition 

int main() { 

    cout << Node::c << endl; 
    cout << Node::c << endl; 

    cout << Node::JOB_TYPE << endl; 

    cout << Node::f << endl; 

} 
+0

यदि आप शीर्षलेख में 'नोड' संरचना डालते हैं तो आपको केवल समस्या होगी और आप इसे 2 फाइलों में शामिल करेंगे। –

+1

यह एक बहुत अच्छा सवाल है - इस मस्तिष्क कोशिकाओं को इस रविवार को धक्का दे रहा है। धन्यवाद –

+2

फ़्लोटिंग-पॉइंट के लिए पिकुलियर नियम आमतौर पर क्रॉस-कंपाइलर्स के बारे में चिंताओं के कारण होते हैं, यानी, एक सिस्टम पर चलने वाले कंपाइलर्स लेकिन दूसरे के लिए कोड उत्पन्न करते हैं। लक्ष्य प्रणाली से मेल खाने वाले अभिन्न प्रकारों से निपटने में काफी आसान है; किसी अन्य सिस्टम के फ़्लोटिंग-पॉइंट प्रकारों का विवरण प्राप्त करना अधिक जटिल है। –

उत्तर

8

यहाँ प्रमुख कारण है कि अभिन्न प्रकार (और enum क्योंकि संकलक के अंदर इन किसी प्रकार की पूर्णांकों हो जाते हैं) तुच्छता से प्रतिस्थापित और स्थिरांक के रूप में इस्तेमाल किया जा सकता है।

दूसरे शब्दों में, struct S { static const int x = 42;}, यदि संकलक S::x देखता है, तो यह इसे जेनरेट कोड में निरंतर 42 के साथ तुरंत बदल सकता है। यह float पर लागू नहीं होता है, और निश्चित रूप से std::string जैसे कन्स्ट्रक्टर-निर्भर प्रकारों के लिए नहीं है - संकलक new (या std::string::allocator) पर कॉल किए बिना std::string के लिए स्मृति आवंटित नहीं कर सकता है। इसलिए, स्थिरांक के लिए जिन्हें "निर्मित" होना चाहिए और/या उनके उपयोग के लिए अधिक जटिल मानदंड हैं (एक ऐसे प्रोसेसर के बारे में सोचें जिसमें फ्लोटिंग पॉइंट के लिए हार्डवेयर समर्थन नहीं है - फ़ंक्शन कॉल लोड करने और फ़्लोटिंग पॉइंट मानों को स्टोर करने के लिए कॉल करता है, इत्यादि), भाषा यह निर्धारित नहीं कर सकती है कि इसे करने की अनुमति दी जानी चाहिए।

यदि आप static const std::string S = "test"; के साथ घोषणा शामिल करते हैं, तो कंपाइलर स्टोर Node::S में कितने स्थानों को शामिल करना चाहिए? इसका उपयोग किसके लिए करना चाहिए, जब अंत में यह आपकी तीन अनुवाद इकाइयों को एक प्रोग्राम में जोड़ता है - या इसे अलग-अलग उपयोग करना चाहिए? तब क्या होता है यदि आप const_castNode::S और इसे संशोधित करते हैं? उत्तरार्द्ध यह मानते हुए कि आपके पास एक ऐसा माहौल है जहां यह दुर्घटना का कारण नहीं बनता है, जो पूरी तरह से व्यवहार्य है, और जब तक यह अनिर्धारित व्यवहार नहीं है, मुझे यकीन नहीं है कि संकलक को प्रत्येक अनुवाद इकाई में अलग-अलग मानों का उपयोग करने के रूप में अजीब बनाना चाहिए उस मामले ...

संपादित करें: टिप्पणियों में उल्लिखित अनुसार, सी ++ 11 एक ही तरीके से आगे के प्रकारों का उपयोग करने की अनुमति देता है, इसलिए प्रतिबंधों को आराम दिया जा रहा है क्योंकि संकलक और हार्डवेयर तकनीक में सुधार किया जा रहा है। मुझे शक है क्या आपने कभी static const std::map<X, Y> a = { ... } यद्यपि 'कर सकेंगे के रूप में है कि एक नहीं बल्कि जटिल डेटा प्रकार के निर्माण के लिए है ...

+0

"यहां मुख्य कारण यह है कि अभिन्न प्रकार (और enum क्योंकि कंपाइलर के अंदर ये किसी प्रकार के पूर्णांक बन जाते हैं) को छोटा रूप से प्रतिस्थापित किया जा सकता है और सीधे स्थिरांक के रूप में उपयोग किया जा सकता है।" अधिक आम तौर पर, शाब्दिक प्रकारों का उपयोग इस प्रकार किया जा सकता है रास्ता - शायद हम उम्मीद कर सकते हैं कि नियम इन्हें शामिल करने के लिए आराम किया जाएगा? –

+0

खैर, समस्या यह है कि शाब्दिक भी फ़्लोटिंग पॉइंट वैल्यू हो सकते हैं [सुनिश्चित नहीं हैं कि अन्य भी हैं), और उन्हें अक्सर विशेष उपचार की आवश्यकता होती है - विशेष रूप से उन हार्डवेयर पर जिन्हें फ्लोटिंग पॉइंट के लिए अंतर्निहित समर्थन नहीं मिला है। –

+1

@ChrisBeck "आराम किया जाएगा" -> "आराम से हैं"। http://melpon.org/wandbox/permlink/1qxlfeqKMVWoeti7 और अधिक आम तौर पर, सभी शाब्दिक प्रकार, [class.static.data] p3 – dyp

0

std::string का आरंभ कुछ कोड रन समय में निष्पादित करने के लिए की आवश्यकता है।

स्ट्रिंग शाब्दिक के साथ एक पॉइंटर शुरू करने के लिए स्मृति में कहीं भी स्ट्रिंग को चलाने की आवश्यकता होती है, रन टाइम में भी।

संबंधित मुद्दे

 संबंधित मुद्दे