C ++ जहां स्थैतिक कास्ट को इनिशियलाइज़ करना है


129

मुझे कक्षा में जाना है

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

sस्रोत फ़ाइल में स्ट्रिंग को इनिशियलाइज़ करने के लिए सबसे अच्छी जगह कहाँ है ?

जवाबों:


178

कहीं भी एक संकलन इकाई (आमतौर पर एक .cpp फ़ाइल) में होता:

foo.h

class foo {
    static const string s; // Can never be initialized here.
    static const char* cs; // Same with C strings.

    static const int i = 3; // Integral types can be initialized here (*)...
    static const int j; //     ... OR in cpp.
};

foo.cpp

#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;

(*) मानकों के अनुसार आपको iकक्षा परिभाषा के बाहर परिभाषित करना चाहिए (जैसे jहै) यदि यह कोड में केवल अभिन्न स्थिर अभिव्यक्तियों के अलावा अन्य में उपयोग किया जाता है। विवरण के लिए डेविड की टिप्पणी नीचे देखें।


27
मैंने उत्थान किया है, लेकिन मानक की समीक्षा करने के बाद आपके कोड में एक त्रुटि है: cpp में परिभाषित कियाi जाना चाहिए । §9.4.2 / 4 यदि एक स्थैतिक डेटा सदस्य कास्ट इंटीग्रल या कॉस्ट एन्यूमरेशन प्रकार का है, तो क्लास डेफिनेशन में इसकी घोषणा एक निरंतर- आरम्भक को निर्दिष्ट कर सकती है जो एक अभिन्न स्थिर अभिव्यक्ति (5.19) होगी। उस स्थिति में, सदस्य अभिन्न निरंतर अभिव्यक्तियों में प्रकट हो सकता है। सदस्य को अभी भी एक नाम-स्थान दायरे में परिभाषित किया जाएगा यदि यह कार्यक्रम में उपयोग किया जाता है और नेमस्पेस स्कोप परिभाषा में इनिशियलाइज़र नहीं होगा।
डेविड रॉड्रिग्ज़ - dribeas

3
मानकों से आपकी बोली के आधार पर, ऐसा लगता है कि इसे केवल तभीi परिभाषित किया जाना चाहिए जब इसे अभिन्न निरंतर अभिव्यक्तियों के बजाय कहीं और इस्तेमाल किया गया, सही? इस मामले में आप यह नहीं कह सकते हैं कि कोई त्रुटि है क्योंकि यह सुनिश्चित करने के लिए पर्याप्त संदर्भ नहीं है - या कड़ाई से बोलना उपरोक्त उदाहरण सही है यदि कोई अन्य कोड नहीं है। अब मैं आपकी टिप्पणी (+1) की सराहना करता हूं, मैं अभी भी चीजें सीख रहा हूं! इसलिए मैं उत्तर में उस बिंदु को स्पष्ट करने की कोशिश करूंगा, कृपया मुझे बताएं कि क्या यह बेहतर है ...
स्क्वीलर

@squelart क्षमा करें यदि मैं गूंगा हूं, लेकिन अभिन्न स्थिर अभिव्यक्ति के अलावा बयान का एक उदाहरण होगा?
सकशम

3
उदाहरण के लिए @Saksham किसी फ़ंक्शन को कॉल करने के लिए, उदाहरण के लिए: int f() { return 42; } class foo { static const int i = f(); /* Error! */ }ध्यान दें कि C ++ 11 'कॉन्स्टैक्सप्र' फ़ंक्शन को कॉल करने की अनुमति देता है:constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
गिलहरी

@squelart मैं पाठ को ऐसे पढ़ता हूं कि यदि सदस्य का उपयोग किया जाता है तो परिभाषा की आपूर्ति की जानी चाहिए - मानक में शब्दांकन उस आवश्यकता को निरंतर अभिव्यक्ति को अभिन्न करने के लिए सीमित नहीं करता है।
व्लादोसोव

12

स्टेटिक सदस्यों को फ़ाइल स्कोप पर या उपयुक्त नेमस्पेस में एक .cpp अनुवाद इकाई में आरंभीकृत किया जाना चाहिए:

const string foo::s( "my foo");

11

एक ही नाम स्थान के भीतर अनुवाद इकाई में, आमतौर पर शीर्ष पर:

// foo.h
struct foo
{
    static const std::string s;
};

// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives

// bar.h
namespace baz
{
    struct bar
    {
        static const float f;
    };
}

// bar.cpp
namespace baz
{
    const float bar::f = 3.1415926535;
}

8

चूंकि C ++ 17 इनलाइन विनिर्देशक चर पर भी लागू होता है। अब आप वर्ग परिभाषा में स्थिर सदस्य चर को परिभाषित कर सकते हैं:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};

1

केवल अभिन्न मान (उदाहरण के लिए static const int ARRAYSIZE) को हेडर फ़ाइल में आरंभीकृत किया जाता है क्योंकि वे आमतौर पर क्लास हेडर में उपयोग किए जाते हैं जैसे कि किसी सरणी के आकार को परिभाषित करने के लिए। कार्यान्वयन फ़ाइल में गैर-अभिन्न मानों को प्रारंभ किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.