'स्थैतिक कार्य' कब उपयोग में आते हैं?


25

ठीक है, मैंने सीखा है कि एक स्थिर कार्य क्या है, लेकिन मैं अभी भी नहीं देखता कि वे निजी सदस्य कार्यों की तुलना में अधिक उपयोगी क्यों हैं। यह यहां एक नए-ईश प्रश्न की तरह हो सकता है, लेकिन इसके बजाय सभी निजी सदस्य कार्यों को स्थैतिक कार्यों से क्यों नहीं बदला जाए?


1
ऐसा नहीं होना चाहिए "निजी सदस्यों के कार्यों के साथ सभी स्थिर कार्यों को प्रतिस्थापित करें"? वर्तमान में, आप यह कह रहे हैं कि आप स्थैतिक विधियों के बिंदु को नहीं देखते हैं और यह पूछने के लिए जाते हैं कि हम उनमें से अधिक का उपयोग क्यों नहीं करते हैं।

5
"स्थिर कार्य" क्या है? C ++ में, कम से कम दो अर्थ हैं (और अंतिम बार मैंने C ++ 11 ड्राफ्ट को देखा था, उन्होंने staticकार्य
दायरों

क्या आप का मतलब है "स्थिर फ़ंक्शन" के अर्थ में सी-सी ++ में फ़ाइल-स्कोप स्टैटिक फ्री फंक्शन या "स्टैटिक मेमनबेर फंक्शन / मेथड" के रूप में? यह बहुत बड़ा अंतर है!
जनवरी को जन हडेक

@ जानहुडेक: मुझे लगता है कि private memberहम की उपस्थिति को देखते हुए हम यह मान सकते हैं कि ओपी ओओ अवधारणा के बारे में ओपी पूछ रहा है और फ़ाइल-स्कोप स्टैटिक के बारे में कोई सुराग नहीं है।
मैथ्यू एम।

@ मैथ्यूएमएम: वास्तव में 'प्राइवेट मेंबर' की उपस्थिति वास्तव में मुझे इस बात पर विश्वास करने के लिए प्रेरित करती है कि वह C ++ के अर्थों में स्थिर कार्य करता है। क्योंकि फ़ाइल-स्कोप्ड स्टैटिक फ़ंक्शंस और प्राइवेट मेंबर फ़ंक्शंस वो दो चीज़ें हैं जिनका C ++ में समान उपयोग होता है, जबकि पब्लिक स्टेटिक मेंबर को प्राइवेट नॉन-स्टैटिक मेंबर के साथ रिप्लेस करने का कोई मतलब नहीं है। दुर्भाग्य से ओपी जवाब नहीं दे रहा है।
जन हडेक

जवाबों:


25

यह मानते हुए कि आप OOP का उपयोग कर रहे हैं , स्थैतिक कार्यों का उपयोग करें जब वे किसी भी वर्ग के सदस्यों पर निर्भर नहीं होते हैं। वे अभी भी निजी हो सकते हैं, लेकिन इस तरह से उन्हें अनुकूलित किया जाता है क्योंकि वे संबंधित वस्तु के किसी भी उदाहरण पर निर्भर नहीं करते हैं।

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


धन्यवाद बर्नार्ड। Btw, क्या आप जानते हैं कि संकलक के लिए "क्लास के लिए एक विधि को बाँधने" का क्या मतलब है?
डार्क टमप्लर

@ डार्क टेम्पलर: मैं ऐसा नहीं कह सकता। क्या यह किसी विशेष भाषा के लिए विशिष्ट है?
बर्नार्ड

मुझे आपकी परिभाषा के साथ थोड़ी समस्या है "वे किसी भी वर्ग के सदस्यों पर निर्भर नहीं हैं"। सदस्य स्थैतिक कार्य किसी भी गैर-स्थैतिक सदस्य तक नहीं पहुँच सकते, हालाँकि वे स्थैतिक सदस्यों तक पहुँच सकते हैं। स्थैतिक सदस्य वर्ग के सदस्य होते हैं।
न्यूप्रिंट

@newprint: आप सही हैं, हालांकि यह वह नहीं है जो मैंने कहा था। मैंने कहा जब वे किसी भी वर्ग के सदस्यों पर निर्भर नहीं होते हैं। स्थैतिक सदस्यों का उपयोग करना ठीक है यदि वे आवश्यक हैं, लेकिन यह हमेशा मामला नहीं हो सकता है।
बर्नार्ड

8

उपरोक्त (बहुत अच्छे) की तुलना में अधिक सरलीकृत स्पष्टीकरण के लिए कोशिश कर रहा है।

एक वस्तु कोड + डेटा सामान्य रूप से है। एक स्थिर विधि का उपयोग तब किया जाता है जब आपके पास निपटने के लिए केवल "कोड" भाग होता है (कोई डेटा / स्थिति बनाए नहीं रखी जाती है (स्थिर डेटा सदस्यों को छोड़कर)।


5

क्योंकि उन्हें एक उदाहरण की आवश्यकता नहीं है और वे सार्वजनिक हो सकते हैं। मान लें कि आपको सबसे बड़ी सामान्य भाजक प्राप्त करने के लिए एक फ़ंक्शन की आवश्यकता है (जीसीडी, अंश वर्गों के लिए बहुत उपयोगी है; और हाँ यह सिर्फ एक सरल उदाहरण है)। वस्तुओं का एक वर्ग बनाने का कोई मतलब नहीं है जिसका एकमात्र उद्देश्य यह है कि आपके पास एक ऐसा thisसंकेतक हो सकता है जिसकी आपको न तो आवश्यकता हो और न ही इसमें उपयोग हो gcd। तो आप इसके लिए एक स्थिर विधि का उपयोग करते हैं, आदर्श रूप से उस वर्ग पर जो वास्तव में जीसीडी (जैसे कि अंश वर्ग में) का उपयोग करता है।

अगर केवल स्थैतिक विधियाँ हैं, तो आप गलत कर रहे हैं और या तो वास्तव में OOP कर रहे हैं या अपने प्रतिमान के लिए अधिक उपयुक्त भाषा का उपयोग करना चाहिए।


क्या निशुल्क फ़ंक्शन का उपयोग करना आपके उदाहरण में बेहतर नहीं होगा?
इला May२ El२

2
@ Ela782 यदि भाषा के मुफ्त कार्य हैं, तो हाँ।

ठीक है, आश्वासन के लिए धन्यवाद। मैंने हाल ही में यह सर्वोत्तम अभ्यास सीखा है। हालाँकि, तब मैं इस समय यह देख रहा था कि सार्वजनिक स्थैतिक सदस्य-कार्य वास्तव में उपयोगी हो सकता है, आइए C ++ जैसी भाषा में कहें। दोनों के लिए उपयोग-मामला तब होता है जब फ़ंक्शन निर्भर नहीं होता है या उसे कक्षा की आवृत्ति की आवश्यकता होती है, और फिर, नि: शुल्क फ़ंक्शन की सिफारिश की जाती है। शायद यह एक नया प्रश्न होना चाहिए।
एला May२ May२

1
@ Ela782 हाँ, यह एक अच्छा सवाल बना सकता है। दो त्वरित बिंदु: विशेष रूप से C ++ में, स्थिर सदस्य टेम्पलेट मेटा प्रोग्रामिंग के लिए उपयोगी होते हैं क्योंकि आप टेम्पलेट पैरामीटर के रूप में एक प्रकार पास कर सकते हैं, लेकिन नाम स्थान नहीं। सामान्य तौर पर, स्थिर कार्यों का उपयोग यह इंगित करने के लिए किया जा सकता है कि फ़ंक्शन वास्तव में किसी वर्ग से निकटता से संबंधित है, जैसा कि केवल नाम स्थान (संबंधित stuff::Thing::Load(...)बनाम stuff::LoadThing()) से संबंधित है ।

2

मैं उन्हें सामान्य कार्यों के लिए सहायक कार्यों के रूप में उपयोग करता हूं, उदाहरण हैं:

  • रेडियन (और इसके विपरीत) में डिग्री परिवर्तित;
  • एक तार को हिलाना;
  • एक एनम से कुछ और में परिवर्तित करना (इस परियोजना में मैं काम कर रहा हूं, वे एक हैश टेबल के रूप में कार्य करते हैं);

मेरी ज्यादातर फाइलें जो स्टैटिक फंक्शंस का समूह हैं, उनका प्रत्यय हेल्पर है, जिसका अर्थ है कि वे जो करते हैं, वह मुझे कहीं और तेजी से लाने में मदद करता है।


2

स्थैतिक विधि क्या है:

स्टैटिक विधियों को न तो कक्षा के उदाहरण की आवश्यकता होती है और न ही वे इस तरह के उदाहरण के डेटा (या स्वयं, मुझे, आदि) तक पहुंच सकते हैं। [ ]

स्थैतिक तरीके कब उपयोगी हैं इसके उदाहरण:

  • वैश्विक / सहायक तरीके
  • डेटा मॉडल क्लास से क्वेरी परिणाम प्राप्त करना (एसपी को कॉल करना)

बस उनका उपयोग करें जहां उपयुक्त हो।

  1. यदि आप अपने आप को कई वस्तुओं में समान विधियों की नकल करते हुए पाते हैं, तो विधि को स्थिर बनाने पर विचार करें ताकि आप DRY का अनुसरण कर सकें।
  2. यदि आपको किसी ऑब्जेक्ट के उदाहरण की आवश्यकता नहीं है, तो आप स्टैटिक विधियों का उपयोग करें (आप ऑब्जेक्ट के इंस्टेंस चर पर काम नहीं कर रहे हैं)

यदि आपका बहुत सारा डेटा वस्तुओं से बाहर है और उन पर स्थैतिक तरीकों से काम किया जा रहा है तो आपका कोड ऑब्जेक्ट ओरिएंटेड नहीं है और इसे बनाए रखना मुश्किल हो सकता है।


1

स्थैतिक और निजी वास्तव में रूढ़िवादी हैं: एक विधि स्थिर, या निजी या कोई भी या दोनों हो सकती है।

स्टेटिक बनाम नॉन-स्टैटिक (उर्फ 'इंस्टेंस मेथड्स') इंगित करता है कि क्या विधि स्वयं क्लास (स्थिर) या किसी विशेष उदाहरण (नॉन-स्टैटिक) पर काम करती है। भाषा के आधार पर, आप एक स्थिर विधि को उदाहरण के माध्यम से कॉल कर सकते हैं, लेकिन आप कभी भी किसी स्थिर विधि के माध्यम से आवृत्ति तक नहीं पहुँच सकते हैं (जिसका अर्थ यह भी है कि आप किसी स्थिर विधि के अंदर से किसी भी गैर-स्थैतिक विधि को नहीं कह सकते हैं, क्योंकि आपके पास कोई नहीं हैthis वस्तु)। व्यवहार को कार्यान्वित करने के लिए स्थैतिक तरीकों का उपयोग करें जो वैचारिक रूप से वर्ग से जुड़ा हुआ है, लेकिन एक विशेष उदाहरण के लिए 'बाइंड' नहीं करता है। एक अन्य परिदृश्य जहां आप स्थैतिक तरीकों का उपयोग करना चाहते हैं, जब आपके पास एक ऐसा फ़ंक्शन होता है जो एक वर्ग के दो उदाहरणों पर काम करता है, और न ही ऑपरेंड एक विशेषाधिकार प्राप्त स्थिति के हकदार हैं - उदाहरण के लिए, मान लें कि आपके पास एक वर्ग हैVector, और आप इसके अलावा लागू करना चाहते हैं; आपकी जोड़ विधि के रूप में बुलाया जा सकता है a.Add(b), लेकिन Vector.Add(a, b)शायद अधिक समझ में आता है।

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

अतः, अंगूठे का नियम:

  • कक्षा के बाहर से बुलाए जाने की आवश्यकता को छोड़कर, सभी सदस्य कार्यों को निजी बनाएं
  • सभी तरीकों को उदाहरण के तरीके बनाते हैं, जब तक कि वे तब भी समझ में न आएं जब तक कि कक्षा का कोई उदाहरण मौजूद नहीं है

0

मैं उपयोगिता वर्गों के लिए C ++ और C # दोनों में स्थिर तरीकों का उपयोग करता हूं, ऐसी कक्षाएं जिनके पास कोई उदाहरण डेटा नहीं है, उपयोगी, संबंधित विधियों के संग्रह को बंडल करने का सिर्फ एक तरीका है।

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();

0

मान लें कि आप C ++ की बात कर रहे हैं (आपने नहीं कहा) और आपके पास शर्तें सही हैं (अर्थात सदस्य कार्यों / विधियों का मतलब नहीं है):

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

दूसरी ओर फ़ाइल-स्कॉप्ड स्टेटिक फ़ंक्शंस को एक सार्वजनिक प्रतीक नहीं मिलता है, इसलिए आप उन्हें जोड़ सकते हैं, संशोधित कर सकते हैं या हटा सकते हैं जैसे कि आप और एक संकलन इकाई से परे कुछ भी कभी भी प्रभावित नहीं होगा।


0

आमतौर पर आपको अपने कार्यक्रम के लिए प्रवेश बिंदु के रूप में कार्य करने के लिए एक स्थिर मुख्य की आवश्यकता होती है। यह महत्वपूर्ण हो सकता है।


0

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

यदि आप इसे हर समय राज्य में दे रहे हैं, तो यह वास्तव में एक स्टेटलेस फ़ंक्शन नहीं है, आप स्टेटलेस फ़ंक्शन को स्टेटलेस सिंटैक्स के साथ बना रहे हैं। उस स्थिति में, यह संभवतः कॉलिंग ऑब्जेक्ट पर होता है, या शायद राज्य को बेहतर संरेखित करने के लिए एक रीफैक्टरिंग और व्यवहार का संकेत दिया जाता है।


0

"क्यों न केवल सभी निजी सदस्य कार्यों को स्थैतिक कार्यों के साथ बदल दिया जाए?"

... क्योंकि एक निजी सदस्य उदाहरण डेटा तक पहुँच प्राप्त कर सकता है, जबकि यह केवल अन्य सदस्य कार्यों के अंदर की गई कॉल से ही होने देता है। स्टेटिक फंक्शन निजी हो सकता है, लेकिन इसका उपयोग तब तक करने में सक्षम नहीं होगा, जब तक कि यह पैरामीटर पैरामीटर के रूप में पारित नहीं हो जाता है।


0

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

यहाँ कुछ और उदाहरण दिए गए हैं:

ओब्ज-सी में, जहाँ उन्हें क्लास मेथड्स कहा जाता है, वे आमतौर पर आवंटन रैपर के रूप में उपयोग किए जाते हैं जहाँ ऑब्जेक्ट को वापस लौटने से पहले संदर्भ काउंटिंग पूल में रखा जाता है।

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

C ++ में एक और उपयोग, जिसके बारे में मैं सोच सकता हूं कि वह त्रुटियों को धीरे से पकड़ सकता है। एक अपवाद को छोड़कर, आपका कंस्ट्रक्टर फ़ंक्शन विफल नहीं हो सकता है। आप एक त्रुटि उदाहरण चर सेट कर सकते हैं, लेकिन यह हमेशा उचित नहीं होता है। इसके बजाय आप उन हिस्सों को कर सकते हैं जो एक स्थिर आवरण में विफल हो सकते हैं और फिर नई वस्तु को आवंटित या वापस कर सकते हैं, या विफलता पर NULL कर सकते हैं।


0

मान लीजिए कि आप किसी चीज़ के साइनस की गणना करना चाहते हैं।

स्थिर के बिना:

Math math = new Math()
double y = math.sin(x)

स्थिर के साथ:

double y = Math.sin(x)

यह sinगैर-स्थिर बनाने के लिए कोई मतलब नहीं है । यह स्टेटलेस है और सिर्फ इनपुट को प्रोसेस करता है।

स्थैतिक कार्य किसी विशेष ऑब्जेक्ट से बंधे नहीं होते हैं। वे "सामान्य" कार्य हैं जो वस्तु की आंतरिक स्थिति से स्वतंत्र हैं।


स्टेटिक तरीके "स्टेटलेस होने की गारंटी नहीं हैं "। हालांकि यह सच है कि वे इंस्टेंस डेटा का उपयोग नहीं कर सकते हैं, लेकिन उनके पास कुछ राज्य (अर्थात स्थिर सदस्य, दोनों का वर्ग जिसके पास स्थिर विधि है और अन्य विश्व स्तर पर दृश्यमान राज्य जैसे अन्य वर्ग के स्थिर चर) तक पहुंच है।

@ डलेन: सच ... आप सही हैं। मैं अभी इसे ठीक कर दूं।
बजे डेगनलीज at

स्थिर के बिना x.sin():। आपका उत्तर मानता है कि पाप "मठ" का एक कार्य होना चाहिए, जबकि यह स्पष्ट रूप से एक डबल पर काम कर रहा है।
AjahnCharles

0

देर से यहाँ की तरह, लेकिन मैं एक सटीक परिभाषा बनाने की कोशिश करना चाहता हूँ: स्थैतिक कार्य ऐसे कार्य हैं जो उदाहरण या गुणों से युक्त नहीं हो सकते हैं जिनमें शामिल वर्ग के तरीके।

कुछ भाषाओं में, C # की तरह, स्थिर कक्षाओं में स्थिर फ़ील्ड या गुण हो सकते हैं, इसलिए यह कहना ठीक नहीं है कि वे राज्य के लिए उपयोग नहीं किए जाते हैं; एक स्थिर कार्य स्थैतिक (वैश्विक) स्थिति का उपयोग कर सकता है।

मूल रूप से, यह उबलता है: स्थैतिक कार्य, जैसे कुछ भी स्थिर होते हैं, उपयोगी होते हैं जब यह उनके लिए हमेशा गैर-स्थिर उदाहरणों पर निर्भरता के साथ उपलब्ध होने के लिए समझ में आता है।

हेल्पर फ़ंक्शंस, जैसे गणित फ़ंक्शंस, एक बार-बार किए गए उदाहरण हैं, लेकिन अन्य हैं।

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

एक और कारण यह हो सकता है कि एक वर्ग है जो एक वैश्विक स्थिति या किसी प्रकार का डेटा रखता है। ऐसे स्थिर कार्य हो सकते हैं जो उस स्थिर वर्ग में स्थिर गुणों या क्षेत्रों के साथ काम करते हैं।


0

मैं स्थिर f () का एक और उपयोग इंगित करना चाहूंगा।

http://www.parashift.com/c++-faq/named-ctor-idiom.html

इसके लिए उबलते हैं: staticफ़ंक्शन आपको "नामित कंस्ट्रक्टर्स" बनाने की अनुमति देते हैं, अर्थात आप अपने स्थैतिक फ़ंक्शन को उपयुक्त और स्व-दस्तावेजीकरण नाम के साथ नाम देते हैं, और यह स्थिर फ़ंक्शन कंस्ट्रक्टरों में से एक को कॉल करता है (क्योंकि कंस्ट्रक्टरों के समान नाम हैं, और आपके पास हो सकते हैं उनमें से बहुत से, उनके बीच अंतर करना मुश्किल हो जाता है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.