5

को देखते हुए आह्वान।अवरोधन सी ++ निहित प्रतिलिपि निर्माता, या इसकी कार्यक्षमता

तब (विचार है कि वर्ग के उदाहरणों में से एक काउंटर है):

Foo aFoo; 
Foo twoFoo=aFoo; 

स्वत: प्रतिलिपि निर्माता आह्वान करेंगे, और इस तरह मैं इस एक गिनती करने से चूक चाहते हैं।

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

+0

(यहाँ लेकिन सिर्फ गिनती,) एक सूचक से निपटने के रूप में एक ही। तीन (पांच सी ++ 11) –

+1

का नियम देखें कॉपी प्रतिलिपि को अधिभारित करें। – user2970916

उत्तर

5

जब से तुम अधिकांश सदस्यों के लिए डिफ़ॉल्ट व्यवहार करना चाहते हैं और केवल एक (स्थिर) सदस्य के लिए विशेष हैंडलिंग की जरूरत है, यही कारण है कि अपने ही वर्ग में है कि विशेष हैंडलिंग संपुटित और उस वर्ग के एक सदस्य चर नहीं? इस तरह:

template<typename T> 
class InstanceCounter 
{ 
public: 
    static int Count; 

    // Automatically invoked when a class containing it is created. 
    InstanceCounter() { Count++; } 

    // Automatically invoked when a class containing it is destroyed. 
    ~InstanceCounter() { Count--; } 

    // Automatically invoked when a class containing it is copy-constructed. 
    InstanceCounter(const InstanceCounter& rhs) { Count++; } 

    // No need to override operator= 

    // Allow this counter to be used as an int.  
    operator int() const { return Count; } 
}; 

template<typename T> 
int InstanceCounter<T>::Count; 

class Foo 
{ 
public: 
    InstanceCounter<Foo> count; 
}; 

कार्यान्वयन नोट:

  • मैं InstanceCounter एक टेम्पलेट बनाया ताकि विभिन्न वर्गों को आसानी से अपने स्वयं के उदाहरण में गिना जाता है हो सकता है।
  • सी ++ 11 के लिए, आप InstanceCounter के लिए एक चालक कन्स्ट्रक्टर और एक चाल असाइनमेंट ऑपरेटर भी प्रदान करना चाहेंगे।

वैकल्पिक रूप से, और शायद बेहतर, CRTP मुहावरा का उपयोग कर:

template<typename T> 
class InstanceCounted 
{ 
public: 
    static int InstanceCount; 

    // Automatically invoked when a class containing it is created. 
    InstanceCounted() { InstanceCount++; } 

    // Automatically invoked when a class containing it is destroyed. 
    ~InstanceCounted() { InstanceCount--; } 

    // Automatically invoked when a class containing it is copy-constructed. 
    InstanceCounted(const InstanceCounted& rhs) { InstanceCount++; } 

    // No need to override operator= 
}; 

template<typename T> 
int InstanceCounted<T>::InstanceCount; 

class Foo : public InstanceCounted<Foo> 
{ 
    // insert class contents here 
}; 
// Now we can access Foo::InstanceCount. 
+1

सीआरटीपी मुहावरे के उपयोग के लिए, मैं फू को इंस्टेंस काउंटर का एक बाल वर्ग बनाने का सुझाव दूंगा। – Serge

+0

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

+1

@ डेविडफेफर हमेशा एक कठिन निर्णय लेते हैं जब स्पष्ट प्रश्न का उत्तर देने वाले दोनों उत्तर होते हैं, साथ ही साथ एक अलग लेकिन बेहतर समाधान प्रदान करते हैं। – Serge

5

क्षमा करें, आपको ओवरलोड और हाथ से कॉपी करने की आवश्यकता होगी।

यदि आप वास्तव में वास्तव में इसके खिलाफ वास्तव में हैं, तो आप एक हैक का उपयोग कर सकते हैं जहां आप स्थैतिक काउंटर और ओवरराइड कॉपी कन्स्ट्रक्टर के साथ एक अमूर्त पैरेंट क्लास बनाते हैं, और आपके वास्तविक डेटा सदस्यों के साथ एक बाल वर्ग और अंतर्निहित उथली प्रतिलिपि निर्माता।

तुम भी एक समझाया वर्ग के थोड़ा कम hacky दृष्टिकोण ले जा सकते हैं। उन मूल्यों को स्टोर करें जिन्हें आप encapsulated कक्षा में कॉपी किया गया है और फिर बाहरी वर्ग स्पष्ट प्रति कन्स्ट्रक्टर को कार्यान्वित करते समय, अपनी अंतर्निहित प्रतिलिपि निर्माता का उपयोग करके आंतरिक कक्षा की उथली प्रति बनाएं।

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