C ++ में प्रोग्रामिंग(Programming) के मॉड्यूल(Module) 16 में आपका स्वागत है। इस मॉड्यूल(Module) में, हम स्टेटिक मेंबर्स(Static Members) के बारे में बात करेंगे; विशेष रूप से हम स्टेटिक डेटा मेम्बर(Static Data Member) और स्टेटिक(static) सदस्य फ़ंक्शन(member function) को समझने की कोशिश करेंगे। रूपरेखा में इन दो प्रकार के सदस्यों को शामिल किया जाएगा, और हम एकाकी ऑब्जेक्ट(object)(singleton) क्लास(class) के बारे में चर्चा करेंगे। रूपरेखा आपकी हर स्लाइड के बाईं ओर दिखाई देगी। एक स्टेटिक डेटा मेम्बर(Static Data Member), हमने डेटा मेंबर्स(Data Members) के बारे में सीखा है। तो, एक डेटा मेम्बर(Data Member) एक क्लास(class) स्ट्रक्चर(structure) का एक घटक है। इसलिए, जब भी किसी ऑब्जेक्ट(object) के संदर्भ में किसी क्लास(class) को त्वरित किया जाता है, तो ऑब्जेक्ट(object) में डेटा मेम्बर(Data Member) होंगे, और जिन डेटा मेंबर्स(Data Members) को हम जानते हैं, उन्हें ऑब्जेक्ट(object) के पॉइंटर(pointer) से या ऑब्जेक्ट(object) के सदस्य कार्यों के भीतर से एक्सेस(access) किया जा सकता है। स्टेटिक डेटा मेम्बर(Static Data Member) के संदर्भ में, चीजें बहुत अलग हैं। स्टेटिक डेटा मेम्बर(Static Data Member) ऑब्जेक्ट(object) से जुड़े नहीं हैं; सामान्य डेटा मेंबर्स(Data Members) की तरह ऑब्जेक्ट(object) से जुड़े होते हैं, लेकिन स्टैटिक डेटा मेम्बर(Static Data Member) इसके विपरीत होते हैं, जिस क्लास(class) के सदस्य सरणी से जुड़े होते हैं। तो, स्टेटिक डेटा मेम्बर(Static Data Member) की महत्वपूर्ण प्रॉपर्टि(property) यह है कि किसी भी क्लास(class) के कितने उदाहरण बनाए जाते हैं, चाहे किसी भी क्लास(class) के स्टेटिक डेटा मेम्बर(Static Data Member) का केवल एक ही उदाहरण होगा। तो, यह कक्षा की सभी ऑब्जेक्ट(object)ओं द्वारा साझा किया जाता है। वास्तव में, अलग-अलग उदाहरणों पर जो दिलचस्प तथ्य हम देखेंगे, वह यह है कि एक स्टेटिक डेटा मेम्बर(Static Data Member) मौजूद हो सकता है, तब भी मौजूद रहेगा, जब क्लास(class) के लिए कोई ऑब्जेक्ट(object) नहीं बनाया गया हो। तो, स्थैतिक सदस्य(Static Member) का उद्देश्य मुख्य रूप से डेटा(Data) को बनाए रखने के लिए जानकारी को बनाए रखना है जो क्लास(class) के लिए विशिष्ट है, लेकिन प्रत्येक और प्रत्येक उदाहरण के लिए विशिष्ट नहीं है। और हम देखेंगे कि कई प्रोग्रामिंग(Programming) स्थितियां हैं, कई समस्याएं हैं जिनके लिए इस तरह के एक स्टेटिक डेटा मेम्बर(Static Data Member) को वास्तव में मदद मिलेगी। आप में से जो जावा के साथ कुछ परिचित हैं, उदाहरण के चर के विपरीत, स्टेटिक(static) डेटा मेम्बर(Data Member) जावा में एक क्लास(class) चर है, जो C ++ में साधारण गैर-स्टेटिक डेटा मेम्बर(Static Data Member) है। स्टेटिक डेटा मेम्बर(Static Data Member) के लिए, हम कुछ अतिरिक्त बाधाओं को देखेंगे; हम देखेंगे कि स्टेटिक(static) डेटा मेम्बर(Data Member) को सामान्य डेटा मेंबर्स(Data Members) की तरह कक्षा के भीतर घोषित किया जाता है। लेकिन इसे उस क्लास(class) के बाहर परिभाषित करने की आवश्यकता है जो स्टेटिक(static) डेटा मेम्बर(Data Member) के लिए मेमोरी बाइंडिंग(memory binding) है जिसे कक्षा के बाहर आमतौर पर एक स्रोत फ़ाइल में किया जाना चाहिए, जिसे प्रारंभ किया जा सकता है। और दिलचस्प तथ्य यह है कि निश्चित रूप से यह स्टेटिक(static) सदस्य है, क्या कोई डेटा मेम्बर(Data Member) एक ऑब्जेक्ट(object) हो सकता है। तो, स्टेटिक डेटा मेम्बर(Static Data Member) भी एक ऑब्जेक्ट(object) है। मुख्य कार्य शुरू होने से पहले स्टेटिक(static) डेटा मेम्बर(Data Member) का निर्माण हो जाता है; यह कुछ ऐसा है जो शायद आपने पहले के मामलों में नहीं देखा है। हमने हमेशा सोचा था कि जब हम निष्पादित करना शुरू करते हैं, तो मुख्य तब होता है जब ऑब्जेक्ट(object)ओं का निर्माण शुरू हो रहा है, लेकिन स्टेटिक(static) सदस्य बना सकते हैं या मुख्य शुरू होने से पहले बनाए जाएंगे और सममित रूप से वे मुख्य रिटर्न(return) के बाद मुख्य समाप्त होने के बाद नष्ट हो जाएंगे। इसलिए, हम इसे उदाहरण के माध्यम से देखेंगे, स्टेटिक डेटा मेम्बर(Static Data Member) सार्वजनिक हो सकते हैं या निजी किसी भी एक्सेस स्पेसियर(access specifier) के लिए संभव है। अब एक स्टेटिक डेटा मेम्बर(Static Data Member) तक पहुँचने के संदर्भ में हमें क्लास(class) नाम का उपयोग करने की आवश्यकता होगी क्योंकि जैसा कि मैंने पहले ही यहाँ उल्लेख किया है कि यह एक क्लास(class) से जुड़ा है न कि ऑब्जेक्ट(object) के साथ। तो, स्टैटिक डेटा मेंबर्स(Data Members) तक पहुँचने के लिए विशिष्ट ऑब्जेक्ट(object) डॉट तरह का नोटेशन(notation) सबसे अच्छा तरीका नहीं है। उन्हें बृहदान्त्र-बृहदान्त्र(colon-colon) या स्कोप रिज़ॉल्यूशन ऑपरेटर(scope resolution operator) का उपयोग करके क्लास(class) नाम से एक्सेस किया जाएगा। और उपयोग के संदर्भ में, स्टेटिक डेटा मेम्बर(Static Data Member) वैश्विक चर के समान व्यवहार के अलावा और कुछ नहीं हैं। एकमात्र अंतर या महत्वपूर्ण अंतर यह है कि वैश्विक चर वैश्विक स्कोप(scope) में मौजूद हैं, लेकिन स्टेटिक(static) डेटा मेम्बर(Data Member) उस क्लास(class) के स्कोप(scope) में हैं जिसमें स्टेटिक(static) डेटा मेम्बर(Data Member) है। इसलिए, वे कार्यक्रम में किसी भी वैश्विक डेटा(Data) के होने की आवश्यकता को समाप्त कर देते हैं। इसलिए, इस परिचय के साथ, मैं आपको एक साधारण उदाहरण के माध्यम से बताता हूं और फिर ये पॉइंट(point) और अधिक स्पष्ट हो जाएंगे। यह एक स्टेटिक डेटा मेम्बर(Static Data Member) का एक उदाहरण है; यह बहुत आसान मामला है। तो, मेरे पास जो कुछ भी है वह एक क्लास(class) है, यह कुछ ऐसा है जो इस क्लास(class) को बहुत सार्थक नहीं करता है, इसे मेरी कक्षा द्वारा बुलाया जाता है और इसमें सामान्य डेटा मेम्बर(Data Member) होता है int x। तो, बाएं कॉलम पर, आप जो देखते हैं, वह स्टेटिक(static) सदस्य का उपयोग नहीं करता है यह वही है जो आपको डेटा मेंबर्स(Data Members) और सदस्य फ़ंक्शन(member function) के संदर्भ में पहले पेश किया गया है। तो, x एक डेटा मेम्बर(Data Member) है, एक सदस्यीय फ़ंक्शन है जो x को 15 से आरंभ करता है। और एक प्रिंट(print) सदस्य फ़ंक्शन(member function) है, जो x का वर्तमान मान लेता है, इसे बढ़ाता है या उसमें 10 जोड़ता है, और फिर उस मान को प्रिंट(print) करता है । तो, ये साधारण सी बात है जिसे हम करने की कोशिश कर रहे हैं। इसलिए, अब यदि हम यहां एप्लिकेशन(application) कोड(code) देखते हैं, तो हम दो ऐसी ऑब्जेक्ट्स(objects) ऑब्जेक्ट(object) 1 और ऑब्जेक्ट(object) 2 का निर्माण कर रहे हैं, जैसा कि आप देख सकते हैं कि मेरी क्लास में कोई कंस्ट्रक्टर(constructor) नहीं है। तो, हम जानते हैं कि मुफ्त डिफ़ॉल्ट(default) निर्माणकर्ता का उपयोग किया जाएगा; और उस कंस्ट्रक्टर(constructor) द्वारा, एक्स को एक विशिष्ट मूल्य में नहीं सौंपा जाएगा। तो, हम ऑब्जेक्ट(object) 1 पर इनवोक प्राप्त करते हैं। इसलिए, यदि हम यहां ऑब्जेक्ट(object) 1 पर प्राप्त करते हैं, तो निश्चित रूप से ऑब्जेक्ट(object) 1 के लिए, इसलिए यदि मैं इसमें आकर्षित कर सकता हूं, तो यह मेरा ऑब्जेक्ट(object) 1 है, यह मेरा ऑब्जेक्ट(object) 2 है, तो मेरे पास x है दोनों मे। और जैसा कि मैं ऑब्जेक्ट(object) 1 के लिए प्राप्त करता हूं, यह 15 हो जाएगा; जैसा कि मैं ऑब्जेक्ट(object) 2 के लिए प्राप्त करता हूं, यह 15 हो जाएगा और फिर अगर मैं प्रिंट(print) करता हूं, तो ऑब्जेक्ट(object) एक के लिए प्रिंट(print) का आह्वान करता हूं, इसलिए यह प्रिंट(print) होगा इस मूल्य को 15 ले जाएगा क्योंकि यहां इसमें 10 जोड़ें। तो, यह 25 हो जाएगा, और इसलिए, यह 25 को प्रिंट(print) करेगा। यह प्रिंट(print) x 25 के बराबर है। इसी तरह, ऑब्जेक्ट(object) 2 के लिए फिर से प्रिंट(print) किया जाता है, यह फिर से यह मान लेता है, जो 15 है जो इसमें 10 जोड़ देता है, क्योंकि मैंने कॉल किया है प्रिंट(print), मान 25 हो जाता है और यही प्रिंट(print) होता है। तो, यह व्यवहार यदि आप देखते हैं तो यह व्यवहार आपके लिए पहले से ही स्पष्ट है। तो, आपको पता चल जाएगा कि मैं ऑब्जेक्टस(objects) ऑब्जेक्ट(object) 1 और ऑब्जेक्ट(object) 2 के साथ एक ही काम कर रहा हूं, और इसलिए, दोनों x के लिए समान मान 25 प्रिंट(print) करते हैं। अब, दाएं कॉलम को देखें, जहां हम स्टेटिक डेटा मेम्बर(Static Data Member) का उपयोग करने का प्रयास कर रहे हैं। तो, मैं एक स्टेटिक(static) सदस्य का उपयोग कैसे करूं, पहले मैं कह रहा था कि यह int x है, अब मैं कह रहा हूं कि यह static int x है। इसलिए, मैंने डेटा मेम्बर(Data Member) घोषणा के सामने कीवर्ड स्टेटिक(static) को उपसर्ग किया है। तो, यह एक गैर-स्टेटिक(static) घोषणा है, यह अब एक स्टेटिक(static) घोषणा बन गई है। अब इस अंतर के साथ यह होता है कि अगर मैं इस तरफ था कि मेरे पास गैर- स्टेटिक(static) डेटा(data) के साथ क्या था, तो मुझे 1 obj, obj 2, डेटा मेम्बर(Data Member) x, डेटा मेम्बर(Data Member) x, यहाँ था जब मैं इस लाइन पर ऑब्जेक्ट(object)ओं का निर्माण करूँगा , मेरे पास obj 1 होगा, मेरे पास obj 2 होगा, लेकिन इनमें से कोई भी ऑब्जेक्ट(object) obj 1 और obj 2 में x का डेटा मेम्बर(Data Member) के रूप में नहीं है, क्योंकि x एक स्टेटिक डेटा मेम्बर(Static Data Member) है और यह किसी विशिष्ट ऑब्जेक्ट(object) से संबद्ध नहीं है। तो, एक और ऑब्जेक्ट(object) है जिसका नाम MyClass:: x, my class:: x है, जो इस क्लास(class) का स्टेटिक डेटा मेम्बर(Static Data Member) x है। तो, आप देख सकते हैं कि जिस क्षण मैं इसे परिभाषित करता हूं वह स्टेटिक(static) है मेरा डेटा मेम्बर(Data Member) ऑब्जेक्ट(object) का हिस्सा नहीं है, न ही ऑब्जेक्ट(object) 1 का हिस्सा है और न ही ऑब्जेक्ट(object) 2 का हिस्सा है, लेकिन यह एक अलग स्थान बन जाता है, यह एक अलग ऑब्जेक्ट(object) बन जाता है। अब केवल एक चीज का नाम x नहीं है, यह MyClass है: x यह कि यह क्लास(class) के नाम से योग्य है और इस तरह से मैं इसे एक्सेस करता हूं। तो, आइए देखें कि जब मैंने उसी एप्लिकेशन(application) का उपयोग करके इसका उपयोग करने का प्रयास किया, जो मेरे पास था, तो इस एप्लिकेशन(application) और मुख्य रूप से इस एप्लिकेशन(application) के बीच कोई अंतर नहीं है। ऑब्जेक्ट(object) ओं का निर्माण हो गया है जैसा हमने देखा है। मुझे मिलता है, तो x को असाइन किया गया है 15. तो, इसका क्या मतलब है x, x यहाँ x है MyClass का x है, इसलिए यह चर है। तो, यह 15 हो जाता है। यह स्टेटिक(static) मूल्य बन जाता है 15। मैं फिर से प्राप्त करने के लिए प्राप्त करने के लिए निष्पादित करता हूं obj 2, उसी x को 15 असाइन किया गया है, क्योंकि x स्टेटिक(static) है यह दो ऑब्जेक्ट(object) ओं के बीच आम है। तो, x को दो बार 15 पर सेट किया गया है। अब मैं obj 1 के लिए प्रिंट(print) का आह्वान करता हूं, तो क्या होगा x का मान 15 है और 10 को इसके साथ जोड़ा जाता है, इसलिए x का मान अब 25 हो जाएगा, क्योंकि 10 को जोड़ दिया गया है, और वह मान है जो प्रिंट(print) हो जाएगा। इसलिए, जब मैं obj1.print x 25 के रूप में मुद्रित किया जाता है। इस पॉइंट(point) तक, गैर-स्थैतिक(static) मामले से व्यवहार में कोई अंतर नहीं है। लेकिन अगले एक पर विचार करें जब प्रिंट(print) को ओबज 2 के लिए लागू किया जाता है। जब ओबज 2 के लिए प्रिंट(print) का आह्वान किया जाता है, तो x का मान अब 25 है, यह अब पंद्रह नहीं है। तो, यह वसीयत, इसमें 10 जुड़ जाएंगे, और अब यह 35 हो जाएगा और x अब 35 हो जाएगा। और इसलिए, जब मैं इस प्रिंट(print) विधि के अनुसार प्रिंट(print) करता हूं तो मेरे द्वारा प्रिंट(print) किया जाने वाला मान 35 हो जाता है, क्योंकि स्थैतिक(static) ऑब्जेक्ट(object) है दोनों ऑब्जेक्ट(object) ओं द्वारा साझा किया गया। इसलिए, जब मैंने दो बार प्रिंट(print) का आह्वान किया है, तो ऑब्जेक्ट(object) 1 के माध्यम से, और ऑब्जेक्ट(object) 2 के माध्यम से एक बार, मूल्य 10 को दो बार x में जोड़ा गया है। और इसलिए, पहले यह 25 था; दूसरे मामले में अब स्टेटिक डेटा मेम्बर(Static Data Member) के साथ, यह 35 हो जाता है, इसलिए यह स्टेटिक डेटा मेम्बर(Static Data Member) का मूल व्यवहार है जिसे हमें सीखना होगा। इसलिए, हमने ध्यान दिया है कि x एक स्टेटिक डेटा मेम्बर(Static Data Member) है, इसे उन दो ऑब्जेक्ट(object)ओं द्वारा साझा किया जाता है जिन्हें हमने देखा है कि वे कैसे साझा की जाती हैं। और यह अगला पॉइंट(point) बहुत महत्वपूर्ण है, मुझे इस पॉइंट(point) को समझाएं। यदि आप यहां स्थैतिक कीवर्ड(static keyword) के अलावा दो कार्यक्रमों की तुलना करते हैं, तो एक अतिरिक्त पंक्ति है जिसे इसमें शामिल किया गया है। हम यह कहते हैं कि जब यह कहते हैं कि यह डेटा मेम्बर(Data Member) स्टेटिक(static) है, तो यह लगभग एक घोषणा है, जिसका अर्थ है कि यह परिभाषित कर रहा है कि यह कह रहा है कि इस चर का नाम x है, यह एक क्लास(class) चर है। क्लास(class) के लिए इसका एक उदाहरण होगा यह प्रकार इंट का है, लेकिन यह किसी भी मेमोरी(memory) को इस चर के साथ नहीं जोड़ता है। जब यह गैर-स्टेटिक(static) होता है, तो मुझे इस बात की कोई परवाह नहीं है, क्योंकि अगर यह गैर-स्टेटिक(static) है, तो मुझे पता है कि कुछ पॉइंट(point) पर कुछ ऑब्जेक्ट(object) तुरंत मिलेगा जैसे obj 1; और जहाँ कहीं भी obj 1 का त्वरित मूल्यांकन होता है, x उसका एक हिस्सा होगा। तो, x को obj 1 की तात्कालिकता के माध्यम से इसकी स्मृति मिल जाएगी, लेकिन स्थैतिक के मामले में यह सिर्फ एक घोषणा है, क्योंकि जब obj 1 को तुरंत मिलेगा क्लास(class) चर x इस ऑब्जेक्ट(object) का एक हिस्सा नहीं है। तो, मुझे मेमोरी(memory) बनाने या इस डेटा मेम्बर(Data Member) के लिए मेमोरी(memory) को बाँधने की आवश्यकता है - स्टेटिक डेटा मेम्बर(Static Data Member) अलग से और यह वह है जिसे एक परिभाषा के रूप में जाना जाता है जिसके माध्यम से मैं इसे बनाता हूं। तो, यह परिभाषा कहती है कि यह वैश्विक स्कोप(scope) में किया जाता है, मैं कहता हूं कि यह चर का नाम है MyClass:: x, क्लास(class) नाम:: चर नाम। प्रकार इंट है। इसलिए, मैं कहता हूं कि प्रकार अंतर है और मैंने वह इनिशियलाइज़ेशन(initialization) रखा है जिसे मैंने यहाँ 0 के रूप में रखा है। यह स्टेटिक डेटा मेम्बर(Static Data Member) को परिभाषित करना है। इसलिए, यदि आप एक प्रोग्राम लिखते हैं जिसमें स्टेटिक डेटा मेम्बर(Static Data Member) है, और यदि आप ऐसा नहीं करते हैं, तो इसे न डालें, तो कंपाइलर यह कहते हुए रोना शुरू कर देगा कि यह विशेष स्टेटिक डेटा मेम्बर(Static Data Member) MyClass: x को परिभाषित नहीं किया गया है, और इसलिए मेमोरी(memory) नहीं मिलती। तो, यह कुछ विशेष है जिसे आपको स्टेटिक डेटा मेम्बर(Static Data Member) के लिए याद रखना होगा कि उन्हें अलग से एक परिभाषा की आवश्यकता होगी और जब प्रोग्राम काम करना शुरू करेगा तो उन्हें इनिशियलाइज़(initialize) करना होगा। तो, यह कब निष्पादित होता है, यह x कब मान 0 प्राप्त करता है, मुख्य के प्रारंभ में प्रारंभ होने से पहले इसे मान 0 प्राप्त होता है। इसलिए, जैसा कि हम प्रोग्राम(program) को निष्पादित करना शुरू करते हैं, पहले सभी वर्गों के सभी स्थैतिक डेटा मेंबर्स(Static Data Members) का निर्माण और आरंभ किया जाएगा, और उसके बाद ही मुख्य काम करना शुरू कर देगा। इसी तरह जब मुख्य केवल उसके बाद समाप्त होता है, तो सभी वर्गों के सभी स्टेटिक(static) डेटा मेम्बर(Data Member) उस उल्टे क्रम में नष्ट होने लगेंगे, जिसमें उनका निर्माण किया गया था। बेशक, इस विशेष उदाहरण में, आप उस निर्माण, विनाश प्रक्रिया को नहीं देखते हैं, क्योंकि इस मामले में स्टेटिक डेटा मेम्बर(Static Data Member) बिल्ट इन टाइप का एक ऑब्जेक्ट(object) है, जहां हम जानते हैं कि कोई स्पष्ट कंस्ट्रक्टर(constructor) या डिस्ट्रक्टर(destructor) उपलब्ध नहीं है। तो, इसके साथ हम आगे बढ़ते हैं, और थोड़ा बड़ा उदाहरण देखते हैं, स्टेटिक डेटा मेम्बर(Static Data Member) का उपयोग करने का अधिक यथार्थवादी उदाहरण। इसलिए, यहाँ हम क्या करने की कोशिश कर रहे हैं, हम एक क्लास प्रिंट(print) जॉब(job) तैयार कर रहे हैं, जिसमें हर प्रिंटिंग जॉब(job) में प्रिंट(print) करने के लिए कई पेज हैं। और जब मैं प्रिंट(print) जॉब(job) ऑब्जेक्ट(object) का निर्माण करता हूं, तो मुझे पता होता है कि इस जॉब(job) में कितने पेज प्रिंट(print) होने चाहिए। अब मैं इसके माध्यम से क्या ट्रैक(track) करना चाहता हूं क्या मैं यह ट्रैक(track) करना चाहता हूं कि निश्चित रूप से मैं यह मान रहा हूं कि ये सभी प्रिंट(print) जॉब्स(jobs) वास्तव में एक प्रिंटर(printer) पर मुद्रण को आग लगाती हैं। इसलिए, कार्य प्रिंट(print) कार्य वास्तव में वहां जाते हैं। इसलिए, मैं दो सूचनाओं को ट्रैक(track) करना चाहता हूं; जैसा कि, वर्तमान में कितने अलग-अलग प्रिंट(print) कार्य हैं, इसलिए मैं उस n जॉब(job) को कॉल करता हूं। अब स्वाभाविक रूप से छपाई के लिए वर्तमान में कितनी जॉब्स(jobs) तैयार हैं, यह विशिष्ट जॉब(job) पर निर्भर नहीं करता है, यह कुल संख्या में प्रिंट(print) जॉब(job) की ऑब्जेक्ट(object) ऊपर निर्भर करता है जो निर्माण किए गए हैं। तो, यह एक प्रॉपर्टि(property) है जो क्लास(class) स्तर पर है, जो एक स्टेटिक(static) प्रॉपर्टि(property) है और इसलिए, मैं इसे एक स्टेटिक(static) इंट एन जॉब्स कहता हूं। इसी तरह, मैं यह कल्पना करता हूं कि जैसे कि मेरे प्रिंटर(printer) में एक प्रिंटिंग ट्रे है जहां एक निश्चित संख्या में पेज लोड किए गए हैं, इसलिए मैं ट्रैक(track) करना चाहता हूं कि उस ट्रे में कितने पेज शेष हैं। इसलिए, मैं n ट्रे पेज डेटा मेम्बर(Data Member) बनाता हूं, जिसे मैं स्टैटिक भी बनाता हूं, क्योंकि यह किसी विशेष कार्य के लिए विशिष्ट नहीं है, लेकिन यह कुल प्रिंट(print) जॉब(job) क्लास(class) के लिए विशिष्ट है कि ट्रे में कितने पृष्ठ शेष हैं। इसके साथ, अब स्वाभाविक रूप से यहाँ इसलिए ये दो स्टेटिक डेटा मेम्बर(Static Data Member) हैं जो इस पॉइंट(point) पर आरंभिक निर्मित और प्रारंभिक हैं और फिर मैं बहुत सारे कार्य करता हूं। मैं शुरू में n जॉब्स(jobs) के मूल्य को प्रिंट(print) करता हूं, जो कि यहां आउटपुट(output) के रूप में 0 होना चाहिए, फिर मैं उन पृष्ठों की संख्या प्रिंट(print) करता हूं जो ट्रे में मौजूद हैं जो 500 के साथ आरंभिक है। इसलिए, आउटपुट(output) 500 होना चाहिए, और फिर मैं एक प्रिंट(print) का निर्माण करता हूं जॉब(job) की ऑब्जेक्ट(object)। इसलिए, मेरी जॉब्स(jobs) की संख्या 1 से बढ़नी चाहिए, और मेरे शेष पृष्ठों की संख्या को उन पृष्ठों की संख्या से घटाया जाना चाहिए, जिन्हें इस जॉब(job) को प्रिंट(print) करना है। इसलिए, इसे 10 से घटाया जाना चाहिए। इसलिए, इस ऑब्जेक्ट(object) के निर्माण के बाद, जब मैं जॉब्स(jobs) और वर्तमान में उपलब्ध पृष्ठों को प्रिंट(print) करता हूं, तो मुझे जॉब(job) मिलती है, अब 0 से 1 इंक्रीमेंट हो गया है, और शेष पेजों की संख्या 490 तक है जो की 500 मूल्य से 10 घटा दी गई है। फिर मैं इस विशेष स्कोप(scope) में आ जाता हूं, जहां मैं दो और ऑब्जेक्ट(object)ओं का निर्माण करता हूं और फिर देखता हूं कि जॉब्स(jobs) का मूल्य क्या है, और पृष्ठों की संख्या 3 हो जाएगी, क्योंकि दो और प्रिंट(print) कार्य चालू हैं, और पृष्ठों की संख्या बढ़ जाती है आगे 30 और 20 से नीचे। तो, यह 30 से 460 कम, 20 उससे कम, 440 हो जाता है, इसलिए शेष पृष्ठों की संख्या है। और फिर मैं ट्रे में पृष्ठों की संख्या को 100 से बढ़ाता हूं, जैसे कि मैं 100 पृष्ठों को लोड कर रहा हूं, इसलिए मेरे पृष्ठों की संख्या 440 हो जानी चाहिए। और फिर मैं इस पॉइंट(point) पर पहुंचता हूं और आप अच्छी तरह से समझ सकते हैं कि चूंकि गुंजाइश जा रही है बाहर, यह ऑब्जेक्ट(object) जॉब(job) 1 और यह ऑब्जेक्ट(object) जॉब(job) 2 जो इस स्कोप(scope) में बनाई गई थी, नष्ट हो जाएगी। इसलिए, अगर वे नष्ट हो जाते हैं तो जॉब्स(jobs) की संख्या 3 से घटकर 1 हो जाएगी। इसलिए, जब मैं यहां प्रिंट(print) करता हूं तो मेरे पास एक काम होता है, और जब मैं शेष पृष्ठों की संख्या प्रिंट(print) करता हूं, तो मैंने 100 और पेज लोड किए हैं, इसलिए यह बन जाता है 540 की संख्या में, इस प्रकार यह व्यवहार करता है। इसलिए, स्थैतिक डेटा मेंबर्स(Static Data Members) का उपयोग करते हुए इस कार्यक्रम में मैं कुछ जानकारी को ट्रैक(track) कर सकता हूं जो हर काम के लिए विशिष्ट नहीं है, लेकिन यह प्रिंट(print) जॉब्स(jobs) के पूरे संग्रह के लिए विशिष्ट है, जो मेरे पास है कि वर्तमान में काम कर रहे प्रिंट(print) जॉब्स(jobs) की संख्या है; जो मूल रूप से एक क्लास(class) की ऑब्जेक्ट(object)ओं की संख्या की गिनती कर रहा है जो वर्तमान में सिस्टम में मौजूद है, और एक वैश्विक संसाधन जो ट्रे में पृष्ठों की संख्या है जिसे मैं हेरफेर कर रहा हूं। तो, यह स्टेटिक डेटा मेम्बर(Static Data Member) का विशिष्ट उपयोग है। अब स्वाभाविक रूप से जैसा कि आप देख सकते हैं कि यहां स्टेटिक डेटा मेम्बर(Static Data Member) सार्वजनिक दृश्यता स्थान में हैं, इसलिए जैसे ही मेरा एप्लिकेशन(application) बदल रहा है, कोई भी वास्तव में आ सकता है और इन मूल्यों को बदलकर केवल एक नया मान प्रदान कर सकता है या वेतन वृद्धि या गिरावट के संदर्भ में बदल सकता है। । इसलिए, मुझे आगे क्या करने की कोशिश करनी चाहिए, उन्हें निजी बनाने की कोशिश करनी चाहिए, ताकि उन्हें सीधे नहीं बदला जा सके। अब निश्चित रूप से अगर मैं उन्हें निजी बनाता हूं तो एक सवाल आता है कि मैं इसमें हेरफेर कैसे करूं? मैं इसे अब और नहीं बदल सकता, क्योंकि अगर मैं इसे निजी बनाता हूं, तो स्वाभाविक रूप से मैं ट्रे में जॉब्स(jobs) की संख्या या पृष्ठों की संख्या के मूल्य को बदल नहीं पाऊंगा। तो, मुझे कुछ फ़ंक्शन की आवश्यकता है जैसे, मेरे पास सदस्य फ़ंक्शन(member function) हैं, जो डेटा मेंबर्स(Data Members) को बदल सकते हैं, मुझे ऐसे कार्यों की आवश्यकता है जो स्टेटिक(static) डेटा मेम्बर(Data Member) मानों को बदल सकते हैं। और यह हमें स्थैतिक सदस्य(Static Member) कार्यों की धारणा में लाता है। अब, स्थैतिक सदस्य(Static Member) कार्यों के बारे में महत्वपूर्ण बात केवल कार्यों की तरह है। वे सामने एक स्थैतिक कीवर्ड(static keyword) के साथ लिखे गए हैं, लेकिन अंतर अन्य सदस्य फ़ंक्शन(member function) के साथ महत्वपूर्ण अंतर है कि उनके पास स्टेटिक(static) सदस्य फ़ंक्शन(member function) नहीं है, इस सूचक पर नहीं है। क्योंकि, जैसे स्टेटिक डेटा मेम्बर(Static Data Member) स्टेटिक(static) सदस्य फ़ंक्शन(member function) भी किसी ऑब्जेक्ट(object) से संबद्ध नहीं है, यह सिर्फ क्लास से जुड़ा हुआ है क्योंकि यह ऑब्जेक्ट(object) से जुड़ा नहीं है, इसमें इस पॉइंटर(pointer) का ऑब्जेक्ट(object) पता नहीं है। इसलिए, इसका परिणाम एक अगला विवरण है क्योंकि यह इस सूचक पर नहीं है, यह ऑब्जेक्ट(object) के डेटा मेंबर्स(Data Members) के पते को नहीं जान सकता है, क्योंकि यह किसी भी ऑब्जेक्ट(object) का संदर्भ नहीं दे रहा है। तो, जिसका अर्थ है कि यह कक्षा के गैर-स्थैतिक डेटा मेंबर्स(Data Members) तक नहीं पहुंच सकता है। यह क्लास(class) के गैर-स्थैतिक सदस्य(Static Member) कार्यों का आह्वान नहीं कर सकता है क्योंकि इस सभी को इस सूचक की आवश्यकता है। तो, इस सूचक पर नहीं होने का एक परिणाम यह है कि स्टेटिक(static) सदस्य फ़ंक्शन(member function) उनमें से किसी को भी एक्सेस नहीं कर सकता है। तो, आप एक स्थैतिक सदस्य(Static Member) फ़ंक्शन(function) का उपयोग कैसे करते हैं, आप स्टेटिक डेटा मेम्बर(Static Data Member) की तरह हैं, आप क्लास(class) नाम का उपयोग करते हुए स्थैतिक सदस्य(Static Member) फ़ंक्शन(function) का आह्वान करते हैं जो कि क्लास का नाम है: स्कोप रिज़ॉल्यूशन ऑपरेटर(scope resolution operator) क्लास का नाम कोलोन-कोलन, सदस्य फ़ंक्शन(member function) का नाम । अब, मैंने पहले ही कहना शुरू कर दिया है कि हमें इनकी आवश्यकता क्यों है, क्योंकि मैं स्थैतिक डेटा मेंबर्स(Static Data Members) को पढ़ना और लिखना चाहता था। जबकि, पहले उदाहरण में, हमने दिखाया कि स्टेटिक डेटा मेम्बर(Static Data Member) सार्वजनिक हैं जिनके पास इनकैप्सुलेशन(encapsulation) समस्याएं हैं? इसलिए, यदि मैं स्टेटिक(static) डेटा मेंबर्स(Data Members) को निजी रूप से एन्क्रिप्ट करता हूं, तो मैं उन्हें स्टेटिक(static) सदस्य कार्यों और स्टेटिक(static) सदस्य कार्यों का उपयोग करके उन्हें हेरफेर करने, पढ़ने और लिखने में सक्षम होऊंगा क्योंकि वे क्लास(class) विशिष्ट हैं वे क्लास(class) विशिष्ट स्थैतिक डेटा मेंबर्स(Data Members) तक पहुंच सकते हैं और बदल सकते हैं उन्हें एक साथ। तो इसका मतलब है कि स्टेटिक(static) डेटा मेंबर्स(Data Members) के साथ-साथ स्टेटिक(static) सदस्य कार्य मुझे फिर से एक समान प्रकार के एनकैप्सुलेशन को लागू करने की अनुमति देगा, हालांकि क्लास स्तर पर ऑब्जेक्ट(object) स्तर पर नहीं। और मैं स्टैटिक डेटा मेंबर स्टेटिक डेटा मेम्बर(Static Data Member) स्टेटिक(static) मेम्बर फ़ंक्शन(member function) और हमारे पास मौजूद स्टेटिक डेटा मेम्बरस(Static Data Members) के साथ इसी तरह के सेट ईडीओम(idiom) बना सकता हूं। यह कुछ पॉइंट(point) पर ध्यान दिया जा सकता है कि स्टेटिक(static) डेटा मेम्बर(Data Member) के पास एक गैर-स्टेटिक(static) सदस्य फ़ंक्शन(member function) के साथ मौजूद नहीं हो सकता है। एक स्टेटिक(static) सदस्य फ़ंक्शन(member function) एक ही नाम के गैर-स्थैतिक सदस्य(Static Member) फ़ंक्शन के साथ मौजूद नहीं हो सकता है जो आपके पास एक क्लास(class) का एक सदस्य फ़ंक्शन(member function) नहीं हो सकता है जो स्टेटिक(static) है, और उसी नाम से एक और है जो गैर-स्टेटिक(static) है, यह अनुमति नहीं है। और निश्चित रूप से स्टेटिक डेटा मेम्बर(Static Data Member) कास्ट नहीं हो सकते हैं, जो इस पॉइंटर(pointer) के नहीं होने का एक परिणाम है, क्योंकि हम जानते हैं कि यदि कोई सदस्य फ़ंक्शन(member function) कोंस्त(const) है, और फिर मूल रूप से इस पॉइंटर(pointer) का प्रकार बदलता है। यह पॉइंटर(pointer) एक स्टेटिक(static) ऑब्जेक्ट(object) के लिए एक पॉइंटर(pointer) बन जाता है, जिसमें स्टेटिक(static) सदस्य फ़ंक्शन(member function) को संदर्भित करने के लिए कोई ऑब्जेक्ट(object) नहीं होता है इसलिए इसे कोंस्टंट(constant) कहेके कॉल करने का कोई मतलब नहीं है। इसके साथ, अब हम वापस जाते हैं और अपने प्रिंट(print) कार्य उदाहरण में सुधार करते हैं जो हमने देखा था। इसलिए, हमने यहां क्या किया है, हमने स्थैतिक सदस्यों(static members) को क्लास(class) घोषणा के निजी हिस्से में स्थानांतरित कर दिया है। इसलिए, अब मुख्य से, आप उन्हें सीधे नहीं बदल सकते हैं उन्हें सीधे बदलना संभव नहीं है, क्योंकि वे अब निजी हैं। इसलिए, हमने स्थैतिक सदस्य(Static Member) कार्यों का एक सेट पेश किया है, जिसका उपयोग उन्हें पढ़ने या लिखने के लिए किया जा सकता है, उदाहरण के लिए, गेटजॉब्स पढ़ता है, वर्तमान में कितनी नौकरियां हैं; चेकपेज पढ़ते हैं, ट्रे में कितने पृष्ठ शेष हैं; loadPages, इस पर और इतने पर नए पृष्ठ लोड करता है। तो, हम इसे फिर से लिखते हैं कि यह एक ही आउटपुट(output) का उत्पादन करने वाला एक ही एप्लिकेशन(application) है, लेकिन इन स्टैटिक डेटा मेंबर्स(Static Data Members) को सीधे एक्सेस करने के बजाय, हम अब स्टेटिक(static) सदस्य फ़ंक्शनस(member functions) का उपयोग करते हैं, जैसे कि मैं जानना चाहता हूं कि कितने जॉब(job) हैं, मैं करता हूं PrintJobs:: getJobs पुन: ध्यान दें कि यह एक क्लास(class) का नाम है:: स्टेटिक(static) सदस्य फ़ंक्शन(member function) नाम। जब मैं PrintJobs करने वाले पृष्ठों की संख्या की जाँच करना चाहता हूँ: checkPages और यह मुझे शेष पृष्ठों की संख्या देगा, मुझे खेद है कि यह इस फ़ंक्शन को लागू करके मुझे यहाँ से शेष पृष्ठों की संख्या प्रदान करेगा। निश्चित रूप से कृपया ध्यान दें कि इन स्टेटिक(static) सदस्य कार्यों में से किसी में भी यह सूचक नहीं है। इसलिए, वे गैर-स्थैतिक डेटा(static data) तक नहीं पहुंच सकते हैं, जैसे उनमें से कोई भी मौजूद nPages डेटा(data) तक नहीं पहुंच सकता है। उन्हें केवल स्थैतिक डेटा(data) के साथ काम करना होगा जो कक्षा के लिए मौजूद हैं। आप इस उदाहरण को बाद में इस पॉइंट(point) पर जा सकते हैं कि आप इस उदाहरण से गुजर सकते हैं, और खुद को समझा सकते हैं कि हमारे पास पिछले मामले की तरह ही कार्यक्षमता है, लेकिन हम इसमें सक्षम हैं एनकैप्सुलेशन(encapsulation) पर सुधार। अब इससे पहले कि हम बंद करें, मैं आपको जल्दी से स्थैतिक सदस्यों(static members) के एक विशिष्ट उपयोग को साकार करने के संदर्भ में दिखाना चाहूंगा, जिसे हम सिंगलटन(singleton) क्लास(class) कहते हैं। एक सिंगलटन(singleton) क्लास एक तरह का डिज़ाइन(design) पैटर्न(pattern) होता है जो कहता है कि एक क्लास को सिंगलटन(singleton) कहा जाता है, अगर आपके पास उस समय केवल एक ही क्लास हो सकती है - एक समय में केवल एक उदाहरण। प्रारंभ में, यह थोड़ा अजीब लगता है कि मुझे ऐसी कक्षाओं की आवश्यकता क्यों है। लेकिन यदि आप सोचते हैं और चारों ओर देखते हैं, तो आप पाएंगे कि भारत के राष्ट्रपति की तरह ही कई वर्गों का व्यवहार होता है, भारत का एक ही राष्ट्रपति होता है, भारत का एक ही प्रधानमंत्री होता है, आईआईटी खड़गपुर का केवल एक निदेशक होता है और इतने पर, कई वर्गों में केवल एक ही उदाहरण है। अब अगर मैं चाहता हूं कि एक क्लास(class) ऐसा हो तो मैं ऐसे क्लास(class) को कैसे लागू करूं? स्वाभाविक रूप से एक क्लास(class) को डिजाइन करना आसान है जिसका कोई उदाहरण नहीं हो सकता है। कंस्ट्रक्टर(constructor) को निजी बनाने के लिए आपको बस इतना करना है। यदि आप कंस्ट्रक्टर(constructor) को निजी बनाते हैं, तो कोई भी इसे कॉल नहीं कर सकता है, और इसलिए, आपके पास उस क्लास(class) का कोई उदाहरण नहीं हो सकता है। लेकिन आप यह कैसे सुनिश्चित कर सकते हैं कि आप केवल एक ऑब्जेक्ट(object) का निर्माण कर सकते हैं, लेकिन एक से अधिक ऑब्जेक्ट(object) का नहीं, इसलिए यह वह चीज है जो स्टैटिक डेटा मेम्बर(Static Data Member) और स्टैटिक सदस्य फ़ंक्शन(static member function) का उपयोग करके बहुत आसानी से किया जा सकता है। इसलिए, आप जो कर रहे हैं, वह एक क्लास(class) है। इसलिए, मैं यह दिखाने की कोशिश कर रहा हूं कि कैसे प्रिंटर(printer) को सिंगलटन(singleton) बनाया जा सकता है, यही स्थिति संगठन में है, संभवत: मेरे पास केवल एक प्रिंटर(printer) है। इसलिए, मुझे यह सुनिश्चित करना होगा कि एक से अधिक प्रिंटर(printer) कभी भी इंस्टेंट न हों। तो, प्रिंटर(printer) क्लास(class) में, ये गैर-स्थैतिक गुण हैं ये केवल पूर्णता के लिए हैं; उस के बारे में चिंता मत करो, लेकिन यहां कंस्ट्रक्टर(constructor) है जिसे निजी बनाया गया है। देखिए यह प्राइवेट पार्ट में है। तो, कोई भी सीधे तौर पर किए गए प्रिंटर(printer) क्लास(class) के किसी भी ऑब्जेक्ट(object) का निर्माण नहीं कर सकता है। निस्संदेह, जनता में रखा जाता है; क्योंकि कंस्ट्रक्टर(constructor) के निजी होने के बाद आप उसका निर्माण नहीं कर सकते। तो, विध्वंसक अभी भी अंदर रह सकता है। अब आप क्या बनाते हैं, आप एक स्टेटिक डेटा मेम्बर(Static Data Member) का परिचय देते हैं, जो एक प्रिंटर(printer) के लिए एक संकेतक है, और इसे निजी में भी रखा जाता है, ताकि कोई भी सीधे नहीं कर सके। तो, आपका विचार यह है कि यह स्टेटिक(static) डेटा मेम्बर(Data Member) जो प्रिंटर(printer) है:: myprinter यह एक ही प्रिंटर(printer) ऑब्जेक्ट(object) को इंगित करेगा जो मेरे पास हो सकता है। अब, ज़ाहिर है, यह है कि मैं इस एकमात्र प्रिंटर(printer) ऑब्जेक्ट(object) का निर्माण कैसे करूं। तो, उसके लिए, जनता में, आप एक स्टेटिक(static) सदस्य फ़ंक्शन(member function) का परिचय देते हैं। इस सदस्य फ़ंक्शन(member function) को प्रिंटर(printer) कहा जाता है। अब यह क्या करता है, जब भी आपको प्रिंटर(printer) की आवश्यकता होती है, जब भी आपको प्रिंटर(printer) ऑब्जेक्ट(object) की आवश्यकता होती है, तो आप ऑब्जेक्ट(object) को सीधे एक्सेस करने की कोशिश नहीं करते हैं, क्योंकि आप नहीं जानते कि ऑब्जेक्ट(object) कहां है। इसके बजाय कि आप क्या करते हैं, आप इस विशेष स्थैतिक सदस्य(Static Member) कार्य को लागू करते हैं, स्थैतिक सदस्य(Static Member) कार्य क्या करता है, यह शुरू में जांचता है, अगर यह प्रिंटर(printer) सूचक शून्य है या अशक्त नहीं है। यहाँ शुरू में ही क्या होगा मैंने परिभाषित किया है और आरंभ किया है। तो, शुरुआत में यह सूचक शून्य होगा, कोई प्रिंटर(printer) नहीं है। यदि यह शून्य है, तो आप एक प्रिंटर(printer) का निर्माण करें और पॉइंटर(pointer) को यहां रखें। तो, आपने प्रिंटर(printer) का निर्माण किया है और इसे यहां रखा है। अब आपको लगता है कि यह विशेष स्टेटिक(static) सदस्य फ़ंक्शन(member function) प्रिंटर(printer) का निर्माण करने में सक्षम है, क्योंकि यह एक सदस्य फ़ंक्शन(member function) है। और इसलिए, यह निजी सदस्यों तक पहुंच सकता है। इसलिए, यह एक नया प्रिंटर(printer) प्राप्त करता है और आपको उस प्रिंटर(printer) को लौटाता है। इसके बाद, जब भी आप इस विशेष स्टेटिक(static) सदस्य फ़ंक्शन(member function) को कॉल करेंगे, तो आप इसे गैर-शून्य पाएंगे। इसलिए, आप इस निर्माण प्रक्रिया को दरकिनार कर देंगे, और आप हमेशा उस प्रिंटर(printer) को वापस करेंगे जो आपने पहले बनाया है। इस प्रक्रिया में, केवल पहला कॉल इस प्रिंटर(printer) ऑब्जेक्ट(object) पर एक नया काम करेगा, और मैं आपको एक प्रिंटर(printer) ऑब्जेक्ट(object) दूंगा; उस पॉइंट(point) से, हर बार हम उसी ऑब्जेक्ट(object) को वापस प्राप्त करेंगे। तो, यदि आप उपयोग में देखते हैं तो यह आप प्रिंट(print) कार्य करना चाहते हैं, इसलिए आप कहते हैं कि प्रिंटर(printer) कोलन कोलोन प्रिंटर(printer) इस भाग का अर्थ है यह सदस्य फ़ंक्शन(member function)। तो, यह सदस्य फ़ंक्शन(member function) तब प्रिंट(print) करेगा, इसलिए यह आपको प्रिंटर(printer) मन लौटाता है यह संदर्भ द्वारा एक रिटर्न है। तो, यह ऑब्जेक्ट(object) प्रिंटर(printer) लौटाता है, इसलिए उस ऑब्जेक्ट(object) प्रिंटर(printer) पर आप प्रिंट(print) प्रिंट(print) लेते हैं जो कि यह गैर-स्टेटिक(static) सदस्य फ़ंक्शन(member function) है और प्रिंटिंग होगी। इसी तरह, आप फिर से 20 का प्रिंट(print) ले सकते हैं। तो, आप देख सकते हैं कि यह प्रिंटर(printer) का निर्माण किया गया है, 10 पृष्ठ मुद्रित हैं, 20 पृष्ठ मुद्रित हैं और इसी तरह। और जब आप स्वाभाविक रूप से हो जाते हैं तो आपने इस ऑब्जेक्ट(object) को बनाया है, इसलिए जिम्मेदारी आपके साथ है कि आप उस ऑब्जेक्ट(object) को नष्ट करें और इसलिए, आप विध्वंसक को बुला सकते हैं और उस ऑब्जेक्ट(object) को नष्ट कर सकते हैं। तो, यह एक सरल तरीका है कि अगर आप स्थैतिक डेटा मेंबर्स(Static Data Members) और स्टेटिक(static) सदस्य कार्यों का उपयोग करते हैं, तो सिंगलटन(singleton) को बहुत सुरक्षित रूप से लागू किया जा सकता है। मैंने इसे एक प्रिंटर(printer) क्लास(class) के साथ दिखाया है, लेकिन यह किसी अन्य क्लास(class) के साथ किया जा सकता है, जिसे सिंगलटन(singleton) की आवश्यकता है। तो, सारांश में, हमने स्थैतिक डेटा मेंबर्स(Static Data Members) और स्टेटिक(static) सदस्य फ़ंक्शन(member function) को पेश किया है, और हमने दिखाया है कि उनका उपयोग कक्षा स्तर पर किसी भी डेटा को बनाए रखने के लिए और विशेष रूप से सिंगलटन(singleton) ऑब्जेक्ट(object) बनाने के लिए ऑब्जेक्ट(object)ओं की गिनती के विभिन्न उद्देश्यों के लिए किया जा सकता है।