आप वास्तव में नहीं हो सकता वाक्यविन्यास आप चाहते हैं। हालांकि, अगर आप कुछ और पूर्वप्रक्रमक जादू कर सकते हैं कि यह काम करने के लिए:
#define CONCAT_HELPER(a,b) a ## b
#define CONCAT(a,b) CONCAT_HELPER(a,b)
#define x ABC
#define MAKENAME(y) CONCAT(x,y)
int MAKENAME(def); // this defines ABCdef variable
int main() {
ABCdef = 0;
return 0;
}
हालांकि, यह एक और दृष्टिकोण का उपयोग करने के लिए एक बेहतर तरीका है, इस तरह के रूप नाम स्थान टिप्पणी में सुझाव दिया है, या और भी बेहतर एक सार कारखाने, कुछ होगा इस तरह:
class Factory {
public:
virtual Printer* getPrinter() = 0;
virtual Writer* getWriter() = 0;
};
class AndroidFactory: public Factory {
public:
virtual Printer* getPrinter() { return new AndroidPrinter(); }
virtual Writer* getWriter() { return new AndroidWriter(); }
};
// the same for IOS, or,
// if you really have such a similar code here,
// you can make a macros to define a factory
...
int main() {
#ifdef ANDROID
Factory* factory = new AndroidFactory();
#else
Factory* factory = new IOSFactory();
#endif
// now just pass factory pointer everywhere
doSomething(old, parameters, factory);
}
(और भी बेहतर auto_ptr
रों या यहाँ तक कि unique_ptr
रों उपयोग करने के लिए किया जाएगा।)
(आप भी अगर आप चाहते हैं अपने कारखाने एक सिंगलटन कर सकते हैं।)
अद्यतन:
एक और दृष्टिकोण दो स्वतंत्र कारखाना वर्गों के लिए और सिर्फ typedef
उनमें से एक का उपयोग करने के लिए है:
class AndroidFactory { // no inheritance here
public:
Printer* getPrinter() {...} // no virtual here!
...
};
class IOSFactory {
...
};
#ifdef ANDROID
typedef AndroidFactory Factory;
#else
typedef IOSFactory Factory;
#endif
// note that we pass Factory* here
// so it will compile and work on both Android and IOS
void doSomething(int param, Factory* factory);
int main() {
Factory* factory = new Factory();
// and pass factory pointer around
doSomething(param, factory);
}
देखें इस दृष्टिकोण का एक और अधिक उन्नत संस्करण के लिए भी TartanLlama का जवाब, सहित चारों ओर एक पॉइंटर पास करने से बचने के लिए स्थिर कार्य।
इस दृष्टिकोण का एक लाभ है कि संकलन समय पर सबकुछ हल हो गया है और कोई वर्चुअल कॉल नहीं किया गया है।
हालांकि, मुझे नहीं लगता कि वर्चुअल फ़ंक्शंस वास्तविक बाधा होगी, क्योंकि कारखाने होने पर इसे कई बार नहीं कहा जाएगा। मुझे लगता है कि अपने उपयोग पैटर्न
Foo* foo = factory.getFoo();
foo->doSomething();
और ज्यादातर समय doSomething()
कॉल में खर्च करते हैं, तो getFoo()
आभासी कॉल भूमि के ऊपर एक टोंटी नहीं होगा किया जाएगा की तर्ज पर कुछ हो जाएगा।
साथ ही, इस दृष्टिकोण के पास एक नुकसान है कि इसमें उचित विरासत संरचना की कमी है और इस प्रकार विस्तार को और अधिक कठिन बनाता है (और स्थिर कार्य विस्तार को और भी कठिन बना देंगे)।
कल्पना कीजिए कि आप एंड्रॉइड फोन और एंड्रॉइड टैबलेट के लिए कुछ अलग कारखानों को रखना चाहते हैं। विरासत के साथ, आपके पास बस एक मूल AndroidBaseFactory
कक्षा होगी जिसमें सामान्य तर्क और फोन और टैबलेट के लिए दो उप-वर्ग होंगे जो आपको चाहिए। विरासत के बिना आपको फैक्ट्री कक्षाओं में सभी सामान्य कार्यक्षमताओं की प्रतिलिपि बनाना होगा (भले ही यह केवल return new AndroidFoo();
कॉल हो)।
इसके अलावा, यूनिट परीक्षण और मॉकिंग विरासत और पॉइंटर्स के आसपास गुजरने के साथ आसान है।
वास्तव में, "सिंगलटन बनाम स्थिर कार्यों का एक गुच्छा" के कई तर्क यहां भी लागू होते हैं।
क्या आप इसके बजाय नेमस्पेस का उपयोग नहीं कर सकते? जैसे 'एंड्रॉइड :: प्रिंटर', 'एंड्रॉइड :: राइटर', आदि – Biffen
नेमस्पेस सबसे अच्छा समाधान प्रतीत होता है (प्रीप्रोसेसर ब्लैक मैजिक से काफी बेहतर)। यह पढ़ने के लिए बस अधिक रखरखाव/आसान है। –