मूल प्रश्न: क्या प्रत्येक वर्चुअल बेस क्लास के स्पष्ट रूप से (गैर-डिफ़ॉल्ट) कन्स्ट्रक्टर को कॉल करने से बचना संभव है?आभासी आधार वर्गों के स्पष्ट कन्स्ट्रक्टर कॉल से बचें
पृष्ठभूमि: मैं विंडोज COM ऑब्जेक्ट्स के आसपास कुछ प्रकार-सुरक्षित सी ++ रैपर कक्षाओं पर काम कर रहा हूं। मेरा वर्तमान दृष्टिकोण CBaseCOMWrapper
वर्ग है जो संदर्भ गणना के लिए IUnknown
ऑब्जेक्ट को समाहित करता है। फिर, मेरे पास CCOMWrapper
टेम्पलेट क्लास है जो CBaseCOMWrapper
से प्राप्त होती है, जो विशिष्ट COM प्रकारों (यानी IDXGIObject
, ID3D11Device
, आदि) के लिए एक रैपर परिभाषित करती है। अंत में, वास्तविक/अतिरिक्त कार्यक्षमता प्रदान करने के लिए अलग-अलग वर्ग इन रैपर टेम्पलेट्स से प्राप्त होते हैं (यानी CDXGIObject
, CD3D11Device
)। ,
बाएँ कॉलम वास्तविक वस्तुओं है:
class CBaseCOMWrapper { };
template<typename T> // here, T should inherit from IUnknown
class CCOMWrapper : public virtual CBaseCOMWrapper { };
class CDXGIObject : public virtual CCOMWrapper<IDXGIObject> { };
template<>
class CCOMWrapper<IDXGIAdapter> : public virtual CCOMWrapper<IDXGIObject> { };
class CDXGIAdapter : public virtual CCOMWrapper<IDXGIAdapter> { };
यहाँ प्रकार पदानुक्रम की इसी आरेख है:
उदाहरण के लिए, मैं निम्नलिखित वर्गों (छोड़े गए सदस्य) है मध्यम कॉलम पतली COM wrappers, और वास्तविक COM ऑब्जेक्ट्स सही कॉलम। ठोस तीर विरासत को दर्शाता है, और धराशायी तीर encapsulation दर्शाता है।
मैं बीच में अभिभावक-बाल संबंध प्रदान करने के लिए CCOMWrapper
के टेम्पलेट विशेषज्ञता का उपयोग करता हूं।
समस्या: रैपर वर्ग एक COM ऑब्जेक्ट में एक गैर-न्यूल (उर्फ वैध) पॉइंटर मानते हैं, इसलिए मेरे पास डिफ़ॉल्ट कन्स्ट्रक्टर नहीं हो सकता है। चूंकि पदानुक्रम "हीरे" से भरा है, इसलिए अधिकांश विरासत आभासी है; इसका मतलब है कि प्रत्येक वर्ग के कन्स्ट्रक्टर को कन्स्ट्रक्टर को कॉल करना होगा। तो, ऊपर दिए गए उदाहरण में, CDXGIAdapter
के निर्माता को CCOMWrapper<IDXGIAdapter>
, CDXGIObject
, CCOMWrapper<IDXGIObject>
, और CBaseCOMWrapper
के रचनाकारों को कॉल करना होगा। चूंकि पदानुक्रम फैलता है (यानी ID3D11Predicate
की विरासत श्रृंखला 4 "लिंक" लंबी है), इसका मतलब है कि अधिक रचनाकारों को बुलाया जाना चाहिए।
संभावित समाधान: आदर्श रूप से, मैं बेस बेस कन्स्ट्रक्टर कॉल उत्पन्न करने के लिए मैक्रोज़ का उपयोग करना चाहता हूं, लेकिन मुझे प्रत्येक COM ऑब्जेक्ट के लिए संपूर्ण विरासत श्रृंखला प्रदान करना होगा; इसके लिए विभिन्न लंबाई की श्रृंखला के लिए विभिन्न मैक्रोज़ की आवश्यकता होगी। हालांकि, सबसे लंबी लंबाई 4 है (मैं केवल डीएक्सजीआई, डी 3 डी 11, और डी 2 डी 1 के साथ काम कर रहा हूं), इसलिए यह सवाल से बाहर नहीं है।
तो मैं सभी रचनाकारों को कॉल करने से कैसे बच सकता हूं? वैकल्पिक रूप से, क्या मैं जो करने की कोशिश कर रहा हूं उसे हासिल करने का एक बेहतर तरीका है?
किसी भी अस्पष्ट/विषम बयान के लिए माफ़ी; मैंने इसे इतिहास वर्ग के मध्य में लिखा: पी –
सी ++ रैपर वर्ग वर्ग का इतिहास? –