2011-12-19 11 views
9

मेरे पास एक सी ++ वर्ग है जो संदर्भ-गणना लागू करता है और मैं चाहता हूं कि इस वर्ग के सभी उपयोगकर्ता केवल इस वर्ग से प्राप्त हो जाएं ताकि कोई ऑब्जेक्ट एक से अधिक संदर्भ काउंटर के साथ समाप्त न हो।एक विशिष्ट वर्ग के लिए आभासी विरासत का पता लगाने और जोर देने के लिए कैसे?

मुझे संकलन समय या कम से कम रनटाइम के दौरान या तो इस आवश्यकता को जोर देने के लिए कुछ तरीका चाहिए।

क्या यह हासिल करने का कोई तरीका है?

उत्तर

5

मुझे लगता है कि कक्षा को लपेटना सबसे आसान विकल्प होगा। रेफ काउंटर से सीधे विरासत में रहने की बजाय एक मध्यस्थ वर्ग बनाएं।

struct RefCounterVirtPrivate_ 
{ 
    int count; 

    RefCounterVirt() 
     : count(0) 
    { } 
}; 

struct RefCounter : public virtual RefCounterVirtPrivate_ 
{ 
}; 

struct A : public RefCounter { }; 
struct B : public RefCounter { }; 
struct C : public A, public B { }; 

फिर सब कुछ आभासी inheritence के बारे में देखभाल करने के लिए किसी भी आवश्यकता के बिना RefCounter से विरासत कर सकते हैं। आपको किसी मौजूदा कोड को भी बदलने की ज़रूरत नहीं है - RefCounter का आभासी उत्तराधिकारी स्वयं हानिरहित होना चाहिए।

यह निश्चित रूप से गारंटी नहीं देता है कि लोगों को RefCounterVirtPrivate_ से सीधे प्राप्त नहीं होता है, लेकिन इसलिए मैंने इसे एक स्पष्ट नाम दिया है। virtual कीवर्ड भूलने से गलती से ऐसा करना मुश्किल है।

0

कुछ चालबाजी के साथ यह संभव होना चाहिए, लेकिन प्रभावों पर विचार करें: आप नीति को स्थापित कर रहे हैं कि ऑब्जेक्ट को तत्काल स्वयं को नष्ट करने की आवश्यकता है यदि उसका संदर्भ काउंटर शून्य तक पहुंचता है।

आपके आवेदन के आधार पर आप सही समय छोड़ने के लिए चाहते हो सकता है जब यह वस्तु के कार्यान्वयन के लिए delete this; कहता है, यानी केवल आधार वर्ग में add_ref() और release() सार कार्यों (जो बनाता है एक ठोस कार्यान्वयन में दिखाने उचित इंटरंकिंग के साथ सभी इंटरफेस vtables) और कंक्रीट वर्ग पर संदर्भ गिनती बनाए रखने का बोझ रखें।

+0

वास्तव में यह कक्षा हर समय इसे 'हटा देती है', इसलिए मैं 'addref() '/' रिलीज() 'में चेक कर सकता था। तो चालबाजी का स्वागत है। – sharptooth

9

ऐसा कुछ?

struct RefCounter { 
    template <typename T> 
    RefCounter(T *) { 
     BOOST_STATIC_ASSERT(boost::is_virtual_base_of<RefCounter, T>); 
    } 
}; 

struct GoodClass : virtual RefCounter { 
    GoodClass() : RefCounter(this) {} 
}; 

struct BadClass : RefCounter { 
    BadClass() : RefCounter(this) {} 
}; 

यह निर्माता के लिए this पारित करने के लिए हालांकि, व्युत्पन्न प्रकार पर कब्जा करने की आवश्यकता होगी, के बारे में शर्म की बात है। और निश्चित रूप से एक जानबूझकर प्राप्त करने वाला उपयोगकर्ता this के अलावा कुछ और पास करके इसे बदल सकता है।

+0

आप 'this' के बजाय सीआरटीपी का उपयोग कर सकते हैं, लेकिन मुझे लगता है कि आपका समाधान बेहतर है। – sbi

+0

@ एसबीआई: मैंने इसे माना, लेकिन फिर 'रेफ काउंटर ' और 'रेफ काउंटर <संदेहजनक>> अलग-अलग वर्ग होंगे, और इसलिए यदि वे वर्चुअल हैं तो भी आप कई रिफाउंटर बेस क्लास सबोबजेक्ट्स के साथ समाप्त हो सकते हैं। –

+0

क्या यह काम दो वर्गों से प्राप्त होता है और एक आधार 'रेफ काउंटर' से वस्तुतः प्राप्त होता है और दूसरा गैर-वर्चुअल रूप से विरासत में मिलता है? – sharptooth

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