ऐसा लगता है कि उत्तर प्रश्न में है - आपके द्वारा सुझाई गई विधि जाने का सही दिशा प्रतीत होता है, सिवाय इसके कि यदि आपके पास उन साझा सदस्यों की बड़ी संख्या है तो आप उन्हें एक संरचना या कक्षा में इकट्ठा करना चाहते हैं और पिछले वर्ग के निर्माता के लिए तर्क के रूप में अतीत।
यदि आप व्युत्पन्न वर्ग के स्थिर सदस्यों के रूप में लागू "साझा" सदस्यों को रखने का आग्रह करते हैं, तो आप व्युत्पन्न कक्षाओं के कोड को स्वतः उत्पन्न करने में सक्षम हो सकते हैं। एक्सएसएलटी ऑटो-जनरेटिंग सरल वर्गों के लिए एक शानदार टूल है।
सामान्य रूप से, उदाहरण "आभासी स्थैतिक" सदस्यों की आवश्यकता नहीं दिखाता है, क्योंकि इन प्रयोजनों के लिए आपको वास्तव में विरासत की आवश्यकता नहीं होती है - इसके बजाय आपको बेस क्लास का उपयोग करना चाहिए और इसे उचित मानों को स्वीकार करना चाहिए कन्स्ट्रक्टर - हो सकता है कि प्रत्येक "उप-प्रकार" के लिए तर्कों का एक उदाहरण बनाये और साझा डेटा के डुप्लिकेशंस से बचने के लिए इसे पॉइंटर पास कर दिया जाए। एक और समान दृष्टिकोण टेम्पलेट्स का उपयोग करना और टेम्पलेट तर्क को एक वर्ग के रूप में पास करना है जो सभी प्रासंगिक मान प्रदान करता है (इसे आमतौर पर "नीति" पैटर्न के रूप में जाना जाता है)।
निष्कर्ष निकालने के लिए - मूल उदाहरण के उद्देश्य के लिए, ऐसे "वर्चुअल स्थिर" सदस्यों की कोई आवश्यकता नहीं है। यदि आपको अभी भी लगता है कि आपके द्वारा लिखे गए कोड के लिए उन्हें जरूरी है, तो कृपया विस्तृत करने और अधिक संदर्भ जोड़ने का प्रयास करें।
क्या मैं ऊपर वर्णित का उदाहरण:
class BaseClass {
public:
BaseClass(const Descriptor& desc) : _desc(desc) {}
string GetName() const { return _desc.name; }
int GetId() const { return _desc.Id; }
X GetX() connst { return _desc.X; }
virtual void UseClass() = 0;
private:
const Descriptor _desc;
};
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass(Descriptor("abc", 1,...)) {}
virtual void UseClass() { /* do something */ }
};
class DerDerClass : public BaseClass {
public:
DerivedClass() : BaseClass("Wowzer", 843,...) {}
virtual void UseClass() { /* do something */ }
};
मैं इस समाधान पर विस्तृत करने, और शायद de-प्रारंभ समस्या का समाधान देने के लिए करना चाहते हैं:
एक छोटा सा परिवर्तन के साथ
, आप व्युत्पन्न वर्ग के प्रत्येक उदाहरण के लिए "वर्णक" के एक नए उदाहरण के बिना उपरोक्त वर्णित डिज़ाइन को कार्यान्वित कर सकते हैं।
आप एक सिंगलटन वस्तु, DescriptorMap, कि प्रत्येक डिस्क्रिप्टर का एक उदाहरण का आयोजन करेगा बना सकते हैं और इसका इस्तेमाल करते हैं जब इतनी तरह ली गई वस्तुओं का निर्माण:
:
enum InstanceType {
Yellow,
Big,
BananaHammoc
}
class DescriptorsMap{
public:
static Descriptor* GetDescriptor(InstanceType type) {
if (_instance.Get() == null) {
_instance.reset(new DescriptorsMap());
}
return _instance.Get()-> _descriptors[type];
}
private:
DescriptorsMap() {
descriptors[Yellow] = new Descriptor("Yellow", 42, ...);
descriptors[Big] = new Descriptor("InJapan", 17, ...)
...
}
~DescriptorsMap() {
/*Delete all the descriptors from the map*/
}
static autoptr<DescriptorsMap> _instance;
map<InstanceType, Descriptor*> _descriptors;
}
अब हम ऐसा कर सकते हैं
class DerivedClass : public BaseClass {
public:
DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.BananaHammoc)) {}
virtual void UseClass() { /* do something */ }
};
class DerDerClass : public BaseClass {
public:
DerivedClass() : BaseClass(DescriptorsMap.GetDescriptor(InstanceType.Yellow)) {}
virtual void UseClass() { /* do something */ }
};
निष्पादन के अंत में, जब सी रनटाइम अनियंत्रण करता है, तो यह हमारे ऑटोप्रेट समेत स्थैतिक वस्तुओं के विनाशक को भी बुलाता है, जो वर्णनकर्ताओं के हमारे उदाहरण को हटा देता है।
तो अब हमारे पास प्रत्येक वर्णनकर्ता का एक उदाहरण है जिसे निष्पादन के अंत में भी हटाया जा रहा है।
ध्यान दें कि यदि व्युत्पन्न वर्ग का एकमात्र उद्देश्य प्रासंगिक "वर्णनकर्ता" डेटा (यानि वर्चुअल फ़ंक्शंस को लागू करने के विरोध में) की आपूर्ति करना है तो आपको बेस क्लास को गैर-सार बनाने के साथ करना चाहिए, और केवल एक बनाना प्रत्येक बार उपयुक्त वर्णनकर्ता के साथ उदाहरण।