2011-07-07 17 views
7

को छोड़कर गैर प्रतिलिपि मुझे लगता है कि एक वर्ग गैर-प्रतिलिपि बनाने से मुझे मेरी कोड गुणवत्ता के साथ बहुत मदद मिलती है। शुरुआत में मैंने इसे बढ़ावा देने के साथ किया :: noncopyable, लेकिन मुझे वीसी ++ कंपाइलर त्रुटियों को निजी सदस्यों के साथ सहायक नहीं होना चाहिए (कोड में गलत जगह पर डबल क्लिक करना)।सी ++ कभी-कभी

T(T const&); 
T& operator=(T const&); 

वास्तव में, यह मुझे काफी कुछ मामले थे वर्गों संदर्भ वे होना चाहिए जहां के रूप में पारित नहीं हुए को सतर्क कर दिया गया है। इतना तो, कि मैं कक्षाओं पर भी एक चेतावनी प्राप्त करना चाहता हूं कि मुझे केवल एक बार निर्माण की प्रतिलिपि बनाने की आवश्यकता है।

क्या ऐसा करने का कोई अच्छा तरीका है? मैं दो तरीकों से निजी छोड़ने और सार्वजनिक टी (टी कॉन्स &, बूल डमी) कन्स्ट्रक्टर जोड़ने के उदाहरण के लिए सोच रहा था जब मैं वास्तव में निर्माण की प्रतिलिपि बनाना चाहता हूं। या वैकल्पिक रूप से दो तरीकों से सार्वजनिक रूप से बना सकते हैं और किसी भी तरह से प्रतिलिपि बनाते समय एक संकलक चेतावनी को सक्रिय करते हैं, जहां मैं चाहता हूं चेतावनी दबाने।

या शायद सभी एक साथ बेहतर तरीका है?

उत्तर

6

यह सुनिश्चित नहीं है कि यह वही है जो आप चाहते हैं, लेकिन यदि आप कॉपी कन्स्ट्रक्टर explicit को चिह्नित करते हैं तो कक्षा मूल्य या प्रति-प्रारंभिक द्वारा पारित नहीं की जा सकती है, लेकिन आप प्रत्यक्ष प्रारंभिकरण का उपयोग करके प्रतिलिपि बना सकते हैं।

आप शायद असाइनमेंट ऑपरेटर को निजी रखना चाहते हैं, शायद NonAssignable आधार इसके लिए उपयोगी होगा।

+1

मुझे यह जवाब सबसे अच्छा लगता है। कॉपी अनुभवकर्ताओं के साथ समस्या, मेरे अनुभव में, जब वे कुछ विशाल वस्तु पर "दुर्घटना से" आह्वान करते हैं। 'स्पष्ट' आपको इसके बारे में सोचने के लिए मजबूर करता है जब आप उन्हें बुलाते हैं, जो पर्याप्त होना चाहिए। – Nemo

+0

चीयर्स, यह मेरी आवश्यकताओं के अनुरूप है। धन्यवाद। – Cookie

2

मुझे लगता है कि आपने स्वयं को एक आदर्श तरीके से नामित किया है। (?)

मैं सिर्फ एक साफ थोड़ा चाल मैं एक बार एक और कोड बेस मैं पर काम किया में खेला याद किया:

struct T 
{ 
    friend class SomeClientThatCanConstructT; 
    T(T const&); 

    private: 
    T(T const&);   
}; 

के रूप में टिप्पणी में चर्चा की निम्नलिखित उड़ नहीं होगा

आप एक स्पष्ट नाम (जैसे CopyConstruct) चुन सकते हैं और आरवीओ पर समान रूप से कुशल होने के लिए भरोसा कर सकते हैं:

struct T 
{ 
    inline T CopyConstruct() const  { return *this; } 
    inline T& AssignTo(T& dst) const { return dst = *this; } 
    inline T& AssignFrom(const T& src) { return *this = src; } 

    private: 
    T(T const&); 
    T& operator=(T const&); 
}; 

+0

मैंने इसके बारे में सोचा लेकिन आपकी 'CopyConstruct' की आवश्यकता है कि प्रतिलिपि बनाने योग्य हो, भले ही संकलक इसे कॉल न करे। –

+0

श्यूट। मुझे याद दिलाने के लिये धन्यवाद। यह वास्तव में एक स्टॉपर है। बेशक आप इसे सभी तरह से गले लगा सकते हैं, लेकिन कन्स्ट्रक्टर कॉल के लिए, वास्तव में आपके 'टैग पैरामीटर' समाधान का कोई विकल्प नहीं है। इसके बारे में सोचने के लिए आओ, मुझे अचानक यह याद रखना याद है ...उत्तर – sehe

+0

अद्यतन कर रहा है कि दोस्त थोड़ा सा चाल चल रहा है। –

0

आप संभवतः एक T का निर्माण और उसके बाद का उपयोग करने के assign विधि जोड़ने के लिए डिफ़ॉल्ट सकता है। यद्यपि यह पूरी तरह इष्टतम प्रतीत नहीं होता है, यह दर्शाता है कि आप अपनी प्रतिलिपि आवश्यकताओं की समीक्षा करना चाहेंगे।

0

मुझे एक प्रकार को प्रतिबंधित करने का विचार पसंद नहीं है (CopyConstructible पूरे stdlib में एक भारी उपयोग की जाने वाली अवधारणा है) क्योंकि इसका दुरुपयोग किया जा सकता है। यदि आप किसी अन्य ऑब्जेक्ट से ऑब्जेक्ट बना सकते हैं, तो इसे प्रतिलिपि बनाना चाहिए। यह पाठक को किसी भी वास्तविक उद्देश्य की सेवा किए बिना महत्वपूर्ण कोड से भी परेशान करता है।

शायद कॉपी कन्स्ट्रक्टर द्वारा ट्रिगर किए गए डीबग मोड में एक चेतावनी या दावा वास्तव में आप क्या देख रहे हैं?

+0

क्या ऐसी कोई बात है? जैसे क्या संकलक या लिंकर किसी फ़ंक्शन से लिंक होने पर उपयोगकर्ता द्वारा परिभाषित चेतावनी को परिभाषित कर सकता है? और तब ऑब्जेक्ट फ़ाइल में चेतावनी दबाएं जो मैं चाहता हूं? एक प्रगति चेतावनी की तरह अक्षम? – Cookie