2015-11-26 4 views
13

मैं समझने की कोशिश कर रहा था कि this blog पढ़कर शून्य का नियम क्या कहता है। आईएमओ, यह कहता है कि यदि आप अपना खुद का विनाशक घोषित करते हैं तो चालक कन्स्ट्रक्टर बनाना और डिफ़ॉल्ट रूप से असाइनमेंट को स्थानांतरित करना न भूलें।विनाशक अंतर्निहित चाल तरीकों की पीढ़ी को अक्षम क्यों करता है?

Example:

class Widget { 
public: 
    ~Widget();   // temporary destructor 
    ...    // no copy or move functions 
}; 

"नाशक के अलावा इस कदम कार्यों का पीढ़ी को निष्क्रिय करने के पक्ष प्रभाव पड़ता है, लेकिन क्योंकि विजेट copyable है, सभी कोड चाल उत्पन्न करने के लिए प्रयोग किया जाता है कि होगा अब प्रतियां उत्पन्न करें। अन्य शब्दों में, कक्षा में विनाशक को संभावित रूप से कुशल चालों को संभावित रूप से कम-कुशल प्रतियों के साथ चुपचाप बदल दिया गया है।

स्कॉट Meyers द्वारा ऊपर पाठ, अंदर उद्धरण मेरे मन में कुछ सवाल उठा:

  • क्यों घोषित नाशक छुपाता चाल अर्थ विज्ञान?
  • घोषित/निश्चित विनाशक केवल चाल semantics छुपाता है या कन्स्ट्रक्टर और प्रतिलिपि असाइनमेंट की प्रतिलिपि बनाता है और साथ ही चाल semantics छुपाता है?
+4

इस नियम के पीछे तर्क था कि यदि आपके कोड एक कस्टम नाशक है, यह शायद इसलिए है क्योंकि एक संसाधन मुक्त कर दिया जाना चाहिए; और यदि किसी संसाधन को मुक्त करने की आवश्यकता है तो चाल के डिफ़ॉल्ट कार्यान्वयन स्रोत वस्तु को एक फर्जी स्थिति में छोड़ सकता है। –

उत्तर

18

"शून्य का नियम" वास्तव में कुछ विशेष सदस्य कार्यों के उत्पन्न होने के दौरान और कुछ के बारे में है। यह कक्षा डिजाइन के लिए एक निश्चित दृष्टिकोण के बारे में है। यह आपको एक प्रश्न का उत्तर देने के लिए प्रोत्साहित करता है:

क्या मेरी कक्षा संसाधनों का प्रबंधन करती है?

यदि ऐसा है, तो प्रत्येक संसाधन को अपनी समर्पित कक्षा में स्थानांतरित किया जाना चाहिए, ताकि आपकी कक्षाएं केवल संसाधनों का प्रबंधन करें (और कुछ और न करें) या केवल अन्य वर्गों को जमा करें और/या समान तार्किक कार्य करें (लेकिन संसाधनों का प्रबंधन न करें) ।

यह एक सामान्य सामान्य एकल उत्तरदायित्व सिद्धांत का एक विशेष मामला है।

जब आप इसे लागू करते हैं, तो आप तुरंत देखेंगे कि संसाधन-प्रबंधन कक्षाओं के लिए आपको मैन्युअल रूप से कन्स्ट्रक्टर को स्थानांतरित करना होगा, असाइनमेंट और विनाशक को स्थानांतरित करना होगा (शायद ही आपको कॉपी ऑपरेशन की आवश्यकता होगी)। और गैर-संसाधन वर्गों के लिए, आपको किसी भी (और वास्तव में आपको नहीं करना चाहिए) की घोषणा करने की आवश्यकता नहीं है: सीटीओ/असाइनमेंट को स्थानांतरित करें, प्रतिलिपि ctor/असाइनमेंट, विनाशक।

इसलिए "शून्य" नाम: संसाधन प्रबंध जब आप अलग वर्गों के लिए और अन्य लोगों, "अन्य" में आप शून्य विशेष सदस्य कार्यों प्रदान करने की आवश्यकता (वे सही ढंग से स्वत: जनरेट हो जाएगा

। वहाँ C++ क्या परिभाषा (एक विशेष सदस्य समारोह के) को रोकता है जो अन्य परिभाषाओं नियम हैं, लेकिन वे केवल शून्य के नियम के मूल को समझने से आपका ध्यान भंग

अधिक जानकारी के लिए देखें:।

  1. https://akrzemi1.wordpress.com/2015/09/08/special-member-functions/
  2. https://akrzemi1.wordpress.com/2015/09/11/declaring-the-move-constructor/
3

लगभग हमेशा, यदि आपके पास विनाशक (वह "कुछ करता है") है, तो आपको "तीन का नियम" का पालन करना चाहिए, जो तब "पांच का नियम" बन जाता है यदि आप अर्थशास्त्र को स्थानांतरित करना चाहते हैं।

यदि आपका विनाशक खाली है, तो इसकी आवश्यकता नहीं है। तो निहितार्थ यह है कि एक गैर-खाली विनाशक (क्योंकि यदि आपकी आवश्यकता नहीं है तो आपके पास एक नहीं होगा!), तो आपको कॉपी और असाइनमेंट ऑपरेशंस में भी वही काम करने की आवश्यकता है, और संभवतः, निर्माण को स्थानांतरित करें और असाइनमेंट की आवश्यकता होगी "कुछ करें" करने के लिए, और न केवल वास्तविक सामग्री को स्थानांतरित करें।

बेशक, ऐसे मामले हो सकते हैं जहां यह सत्य नहीं है, लेकिन संकलक "आवेदक खाली होने पर स्वचालित रूप से स्वचालित रूप से जेनरेट किए गए चाल कार्यों को लागू करते हैं" का दृष्टिकोण लेता है, क्योंकि यह "सुरक्षित" दृष्टिकोण है।

+0

हाय पीट आपकी प्रतिक्रिया के लिए बहुत धन्यवाद, जो आप कह रहे हैं, संकलक अस्पष्ट कदम को छुपाएगा यदि हम स्पष्ट रूप से डीटीओआर (सुरक्षित दृष्टिकोण) को परिभाषित करते हैं ... किस सुरक्षा उद्देश्य संकलक छिपाने के लिए ... मैं प्रतिलिपि पढ़ता हूं चलने की तुलना में ऑपरेशन लागत अधिक है ... छुपा हुआ है हालांकि हम इस कदम को स्पष्ट रूप से परिभाषित करते हैं (मुझे ऐसा नहीं लगता)। –

+0

तो, सामान्य विचार यह है कि "अगर कोई विनाशक नहीं है तो इसे स्थानांतरित करना सुरक्षित है"। एक विनाशक का तात्पर्य है कि वस्तु को नष्ट करने के लिए कुछ विशेष कार्रवाई की आवश्यकता होती है (कुछ हटाना, संदर्भ गणना गिनती आदि)। चलने वाले अर्थशास्त्र में, यह एक प्रतिलिपि बनाने के बजाए ऑब्जेक्ट को "एक तरफ से दूसरी तरफ" स्वैप करके किया जाता है। बेशक, यह "विनाशक में जो कुछ भी करने की ज़रूरत है" के साथ खेलता है, संकलक वास्तव में जानने के लिए असंभव है (जब तक यह समझ में नहीं आता कि विनाशक का क्या प्रभाव है, और इससे पहले कि यह जानना असंभव है !) –

1

की घोषणा कर रहा है/परिभाषित करने Dtor केवल चाल अर्थ विज्ञान छुपाने या कॉपी ctor/कॉपी काम के साथ-साथ कदम अर्थ विज्ञान छिपाने?

कोई उपयोगकर्ता परिभाषित कदम कंस्ट्रक्टर्स एक वर्ग के लिए प्रदान की जाती हैं, तो निम्न में से सभी सत्य है:

  • कोई उपयोगकर्ता के घोषित प्रतिलिपि निर्माता ये हैं
  • देखते हैं कोई उपयोगकर्ता के घोषित कॉपी असाइनमेंट ऑपरेटर
  • कोई उपयोगकर्ता द्वारा घोषित चाल असाइनमेंट ऑपरेटर
  • कोई उपयोगकर्ता द्वारा घोषित विनाशक
  • नहीं हैं

तो कंपाइलर signature T::T(T&&) के साथ अपनी कक्षा के एक गैर-स्पष्ट इनलाइन सार्वजनिक सदस्य के रूप में एक चालक कन्स्ट्रक्टर घोषित करेगा।

इस प्रकार, हाँ एक कॉपी कन्स्ट्रक्टर या असाइनमेंट ऑपरेटर घोषित करने के लिए निहित रूप से घोषित चालक को भी छुपाता है।

+1

मुझे लगता है कि ओपी इन नियमों के पीछे तर्क के लिए पूछ रहा है। – juanchopanza

+0

बहुत धन्यवाद 101010, छिपाने के आधार पर आर 0/आर 3/आर 5 जैसे कोई नियम है या यह कंपाइलर पर निर्भर है। –

+1

कोई भी मानक नियम नहीं हैं सभी कंपाइलर्स उनका अनुसरण करते हैं। – 101010

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