2015-01-16 6 views
5

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

परंपरागत रूप से यह तरीका किया गया था #define NAME 123 लेकिन मुझे एक प्रकार का सुरक्षित विकल्प चाहिए।

कक्षाओं के बाहर आप const int name = 123; कर सकते हैं जो ठीक काम करता है, लेकिन यह कक्षा के अंदर रखना संभव नहीं लगता है।

विजुअल C++ के साथ
class Example { 
    public: 
     const double usPerSec = 1000000.0; 
}; 
double usOneMinute = 60 * Tempo::usPerSec; 

काम करता है, लेकिन जीसीसी साथ काम नहीं करता:

error: non-static const member ‘const double Example::usPerSec’, 
    can’t use default assignment operator 

आप इसे स्थिर बनाने के द्वारा इसे ठीक कर सकते हैं, लेकिन फिर विजुअल C++ शिकायत: उदाहरण इसके लिए

error C2864: 'Example::usPerSec' : a static data member with an in-class 
    initializer must have non-volatile const integral type 
    type is 'const double' 

मुझे लगता है कि इसका मतलब है कि वीसी ++ केवल static const int स्वीकार करेगा।

मैं कन्स्ट्रक्टर में मान को सेट करने से बचना चाहता हूं क्योंकि मुझे मूल्य तक पहुंचने के लिए रनटाइम पर कक्षा का एक उदाहरण चाहिए, जबकि वास्तव में मैं इसे सभी संकलित समय पर संभालना चाहता हूं जैसे #define है।

तो मैं इसे वैश्विक बनाने या #define का उपयोग किए बिना किसी कक्षा के अंदर double के रूप में निरंतर परिभाषित कैसे कर सकता हूं, जो क्लास का उदाहरण किए बिना काम करेगा, और यह प्रमुख सी ++ 03 कंपाइलर्स के साथ काम करेगा ?

उत्तर

10

के किसी भी मामले बना रही है वहाँ अभिन्न और अन्य प्रकार के बीच एक अंतर यहाँ है बिना उपयोग कर सकते हैं।अभिन्न प्रकार के लिए आप हमेशा उन्हें const static सदस्यों के रूप में

struct Example 
{ 
    const static int name = 123; // added 'static' to code in text of question 
    const static unsigned usPerSec = 1000000; 
}; 

गैर अभिन्न प्रकार के लिए के रूप में, परिभाषित कर सकते हैं अपने उदाहरण में इस तरह के रूप double, स्थिति और अधिक जटिल है। 2011 (सबसे compilers के साथ संकलक विकल्प std=c++11 का प्रयोग करके) के बाद से, आप बस यह कर सकते हैं:

struct Example 
{ 
    constexpr static double usPerSec = 1000000.0; 
}; 

लेकिन जीसीसी के साथ, इस

struct Example 
{ 
    const static double usPerSec = 1000000.0; 
}; 

में भी काम करना चाहिए सी ++ 03 (यह एक जीएनयू विस्तार है)।

हालांकि, सी ++ 03 में मानक दृष्टिकोण है, जो भी मानक पुस्तकालय में ही (std::numeric_limits<> में उदाहरण के लिए) द्वारा किया जाता है, एक static सदस्य समारोह

struct Example 
{ 
    static double usPerSec() { return 1000000.0; } 
}; 
+1

'+ 1, मुझे लगता है कि यह एक उपयोगी बिंदु है। – Angew

1

इस कोड को दोनों vC++ और जीसीसी पर काम करता है:

class Example { 
public: 
    static const double usPerSec ; 
}; 
const double Example::usPerSec=10000.0; 
double usOneMinute = 60 * Example::usPerSec; 
4

मैं सी ++ 03 के साथ दो संभावित दृष्टिकोण देखें:

  1. उपयोग एक स्थिर सदस्य समारोह और इनलाइन किए जाने वाले पर भरोसा करते हैं:

    class Example { 
        public: 
         static double usPerSec() { return 1000000.0; } 
    }; 
    double usOneMinute = 60 * Example::usPerSec(); 
    
  2. स्थिर डेटा सदस्य का उपयोग करें और निरंतर फोल्डिंग पर इस्तीफा दें (निरंतर उपयोग करने वाला मान कंप होगा रनटाइम पर uted):

    class Example { 
        public: 
         static const double usPerSec; 
    }; 
    double usOneMinute = 60 * Example::usPerSec; 
    
    // Somewhere in one .cpp 
    const double Example::usPerSec = 1000000.0; 
    
+0

दूसरा विकल्प अनसुलझे बाहरी प्रदान करता है यदि आप इसे पुस्तकालय में उपयोग करते हैं और MSVC++ के साथ संकलित करते हैं। एक डीएलएल में प्रतीक निर्यात करने के लिए निश्चित रूप से एक अनुमानित संकलन-समय स्थिरता के लिए अधिक है जो आमतौर पर लाइब्रेरी के बाहर दिखाई नहीं देगी! 'Std :: numeric_limits <>' का उल्लेख करने के लिए – Malvineous

1

आप इसे स्थिर स्थिरांक बनाने के लिए और फिर इसे कक्षा के बाहर मूल्य देने के लिए है। इसे कन्स्ट्रक्टर के अंदर मत करो। आपको उदाहरण बनाने की आवश्यकता नहीं है

class Example { 
public: 
    static const double usPerSec; 

};

double Example::usPerSec = 1000000.0; 

अब आप इसे कहीं भी वर्ग

double someVar = Example::usPerSec; 
2

है अगर मैं तुम्हें थे मैं डाल यह एक नामस्थान में:

namespace MyExampleNamespace { 
    const double usPerSec = 1000000.0; 
} 
double usOneMinute = 60 * MyExampleNamespace::usPerSec; 
संबंधित मुद्दे