2014-09-09 4 views
7

मूल प्रश्न: क्या प्रत्येक वर्चुअल बेस क्लास के स्पष्ट रूप से (गैर-डिफ़ॉल्ट) कन्स्ट्रक्टर को कॉल करने से बचना संभव है?आभासी आधार वर्गों के स्पष्ट कन्स्ट्रक्टर कॉल से बचें

पृष्ठभूमि: मैं विंडोज COM ऑब्जेक्ट्स के आसपास कुछ प्रकार-सुरक्षित सी ++ रैपर कक्षाओं पर काम कर रहा हूं। मेरा वर्तमान दृष्टिकोण CBaseCOMWrapper वर्ग है जो संदर्भ गणना के लिए IUnknown ऑब्जेक्ट को समाहित करता है। फिर, मेरे पास CCOMWrapper टेम्पलेट क्लास है जो CBaseCOMWrapper से प्राप्त होती है, जो विशिष्ट COM प्रकारों (यानी IDXGIObject, ID3D11Device, आदि) के लिए एक रैपर परिभाषित करती है। अंत में, वास्तविक/अतिरिक्त कार्यक्षमता प्रदान करने के लिए अलग-अलग वर्ग इन रैपर टेम्पलेट्स से प्राप्त होते हैं (यानी CDXGIObject, CD3D11Device)। ,

Type Hierarchy

बाएँ कॉलम वास्तविक वस्तुओं है:

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 के साथ काम कर रहा हूं), इसलिए यह सवाल से बाहर नहीं है।

तो मैं सभी रचनाकारों को कॉल करने से कैसे बच सकता हूं? वैकल्पिक रूप से, क्या मैं जो करने की कोशिश कर रहा हूं उसे हासिल करने का एक बेहतर तरीका है?

+0

किसी भी अस्पष्ट/विषम बयान के लिए माफ़ी; मैंने इसे इतिहास वर्ग के मध्य में लिखा: पी –

+2

सी ++ रैपर वर्ग वर्ग का इतिहास? –

उत्तर

1

तो जैसा कि यह पता चला है, जो मैं पूरा करना चाहता हूं, CCOMWrapper टेम्पलेट अनावश्यक है। मैं सिर्फ एक निर्माता है कि इसी COM ऑब्जेक्ट प्रकार लेता है प्रदान करने के लिए प्रत्येक वर्ग की जरूरत है:

class CDXGIObject : public CCOMObject 
{ 
public: 
    CDXGIObject(IDXGIObject *obj); 
}; 

class CDXGIFactory : public CDXGIFactory 
{ 
public: 
    CDXGIFactory(IDXGIFactory *obj); 
}; 

इस आभासी विरासत की आवश्यकता समाप्त, इस प्रकार मैं आधार कंस्ट्रक्टर्स के सभी अब और कॉल करने के लिए की जरूरत नहीं है।

संबंधित मुद्दे