तीन का नियम C++ के नियमों में से एक है जो अपवाद-सुरक्षित कोड बनाने के लिए अंगूठे के नियमों के अंतर्गत आता है। ये नियम निर्धारित करते हैं कि क्लास के डिफ़ॉल्ट सदस्यों का उपयोग अपवाद-मुक्त अभ्यास के लिए कैसे किया जाना चाहिए।
तीन के नियम को बिग थ्री के नियम या द बिग थ्री के नाम से भी जाना जाता है और यह क्लास के लिए निर्धारित करता है कि यदि कोई क्लास उल्लिखित तीन में से किसी को परिभाषित करता है तो उसे शायद स्पष्ट रूप से सभी तीन को परिभाषित करना चाहिए -
- डिस्ट्रक्टर
- कॉपी कंस्ट्रक्टर
- कॉपी असाइनमेंट कंस्ट्रक्टर
ये तीन क्लास के विशेष सदस्य फ़ंक्शन हैं। यदि प्रोग्रामर द्वारा उनमें से किसी को भी स्पष्ट रूप से परिभाषित नहीं किया गया है, तो कंपाइलर निहित संस्करण प्रदान करता है। यदि उपरोक्त में से कोई एक स्पष्ट रूप से परिभाषित है तो इसका मतलब है कि अन्य दो के लिए निहित संस्करण अनुचित हैं और उन्हें पुनर्परिभाषित किया जाना चाहिए।
ऐसा इसलिए होता है क्योंकि निहित रूप से उत्पन्न कंस्ट्रक्टर और असाइनमेंट ऑपरेटर डेटा सदस्यों की शैलो कॉपी करते हैं। जब क्लास में डायनामिक रूप से आवंटित संसाधनों को इंगित करने वाले पॉइंटर होते हैं तो हमें डीप कॉपी की आवश्यकता होती है।
डिफ़ॉल्ट डिस्ट्रक्टर अप्रयुक्त ऑब्जेक्ट्स को हटा देते हैं। जब कोई कॉपी कंस्ट्रक्टर परिभाषित नहीं होता है तो डिस्ट्रक्टर दो बार चलेगा, एक बार उन ऑब्जेक्ट्स के लिए जिनमें कॉपी होती है और दूसरी बार उन ऑब्जेक्ट्स के लिए जिनसे डेटा सदस्य कॉपी किए गए हैं। इससे बचने के लिए स्पष्ट परिभाषा आवश्यक हो जाती है।
आइए एक उदाहरण से समझते हैं जहां कोई कॉपी कंस्ट्रक्टर और कोई कॉपी असाइनमेंट ऑपरेटर नहीं है, लेकिन डिस्ट्रक्टर मौजूद है -
उदाहरण
#include <stdio.h> class Numbers{ private: int num; int* ptr; public: Numbers( int n, int* p ) //कॉपी कंस्ट्रक्टर{ num =n ; ptr = new int[ num ]; } ~Numbers() //डिस्ट्रक्टर{ delete ptr; ptr = NULL; } }; int main(){ int arr[ 4 ] = { 11, 22, 33, 44 }; Numbers Num1( 4, arr ); // यह समस्या पैदा करता है Numbers Num2( Num1 ); return 0; }
आउटपुट
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001f46c20 *** Aborted
यह इसलिए हुआ क्योंकि प्रोग्राम स्कोप से बाहर जाने पर डिस्ट्रक्टर दो बार कॉल होता है। पहले Num1 का डिलीशन और फिर Num2 का। डिफ़ॉल्ट कॉपी कंस्ट्रक्टर पॉइंटर ptr की कॉपी बनाता है लेकिन उसके लिए मेमोरी आवंटित नहीं करता। इसलिए, जब Num1 हटाया जाता है तो बाद के ptr प्रोग्राम को क्रैश कर देते हैं।