श्रेणी स्थिर चर को हेडर में घोषित किया जा सकता है लेकिन इसे .cpp फ़ाइल में परिभाषित किया जाना चाहिए । ऐसा इसलिए है क्योंकि स्थैतिक चर का केवल एक ही उदाहरण हो सकता है और संकलक यह तय नहीं कर सकता है कि किस ऑब्जेक्ट फ़ाइल को इसे रखा जाए ताकि आपको इसके बजाय निर्णय करना पड़े।
C ++ 11 में घोषणा के साथ एक स्थिर मूल्य की परिभाषा रखने के लिए एक नेस्टेड स्थिर संरचना का उपयोग किया जा सकता है। इस मामले में स्थैतिक सदस्य एक संरचना है और इसे एक .cpp फ़ाइल में परिभाषित किया जाना है, लेकिन मान हेडर में हैं।
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
व्यक्तिगत सदस्यों को शुरू करने के बजाय पूरी स्थिर संरचना को .cpp में आरंभीकृत किया गया है:
A::_Shapes A::shape;
मानों के साथ पहुँचा है
A::shape.RECTANGLE;
या - चूंकि सदस्य निजी हैं और उनका उपयोग केवल A - के साथ किया जाना है
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"} होगा, जो कि लिंकर द्वारा बनाए गए आरंभीकरण के आदेश पर निर्भर करता है।
जैसा कि @ abyss.7 ने उल्लेख किया है कि आप यह भी उपयोग constexpr
कर सकते हैं कि चर का मान संकलन समय पर किया जा सकता है। लेकिन अगर आप अपने तार के साथ घोषित करते हैं 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.
}