2011-10-19 19 views
15

मेयर्स ने अपनी पुस्तक इफेक्टिव सी ++ में उल्लेख किया है कि कुछ परिदृश्यों में गैर-सदस्य गैर-मित्र कार्य सदस्य कार्यों की तुलना में बेहतर encapsulated हैं।मुझे सदस्यों के कार्यों के लिए गैर-सदस्य गैर-मित्र कार्यों को कब प्राथमिकता देना चाहिए?

उदाहरण:

// Web browser allows to clear something 
class WebBrowser { 
public: 
    ... 
    void clearCache(); 
    void clearHistory(); 
    void removeCookies(); 
    ... 
}; 

कई प्रयोक्ताओं, तो WebBrowser भी एक समारोह पेश कर सकती है क्या करने के लिए इन सभी कार्यों को एक साथ प्रदर्शन करना चाहते हैं सिर्फ इतना है कि:

class WebBrowser { 
public: 
    ... 
    void clearEverything(); // calls clearCache, clearHistory, removeCookies 
    ... 
}; 

दूसरी तरह के एक परिभाषित करने के लिए है गैर-सदस्य गैर-मित्र समारोह।

void clearBrowser(WebBrowser& wb) 
{ 
    wb.clearCache(); 
    wb.clearHistory(); 
    wb.removeCookies(); 
} 

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

कार्य clearBrowser तरह सुविधा कार्यों क्योंकि वे एक WebBrowser ग्राहक पहले से ही किसी अन्य तरीके से नहीं मिल सकता है किसी भी कार्यक्षमता प्रदान नहीं कर सकते हैं। उदाहरण के लिए, यदि clearBrowser मौजूद नहीं था, तो ग्राहक clearCache, clearHistory, और removeCookies स्वयं को कॉल कर सकते थे।

मेरे लिए, सुविधा फ़ंक्शन का उदाहरण उचित है। लेकिन गैर-सदस्य संस्करण उत्कृष्ट होने पर सुविधा फ़ंक्शन के अलावा कोई उदाहरण है?

अधिक आम तौर पर, का उपयोग करने के नियम क्या हैं?

+4

मुझे लगता है कि उस विषय के वास्तविक उद्देश्य नियमों की तुलना में अधिक धर्म है। – PlasmaHH

+1

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

+3

@PlasmaHH: मुझे नहीं लगता कि यह धर्म की तरह अधिक है। कुछ कार्य करने के लिए तर्क गैर-सदस्य और गैर-मित्र काफी उचित है। – Nawaz

उत्तर

20

अधिक आम तौर पर, किस समय उपयोग करने के नियम हैं?

यहाँ है क्या स्कॉट मेयर की नियम हैं (source):

स्कॉट जो की सलाह है कि गैर-सदस्य गैर दोस्त कार्यों कक्षाओं के लिए कैप्सूलीकरण में सुधार प्रिंट में एक दिलचस्प लेख है। उन्होंने निर्धारित करने के लिए जहां एक समारोह च रख दिया जाता है निम्नलिखित कलन विधि का उपयोग करता है:

if (f needs to be virtual) 
    make f a member function of C; 
else if (f is operator>> or operator<<) 
{ 
    make f a non-member function; 
    if (f needs access to non-public members of C) 
     make f a friend of C; 
} 
else if (f needs type conversions on its left-most argument) 
{ 
    make f a non-member function; 
    if (f needs access to non-public members of C) 
     make f a friend of C; 
} 
else if (f can be implemented via C's public interface) 
    make f a non-member function; 
else 
    make f a member function of C; 

कैप्सूलीकरण की उनकी परिभाषा कार्य करता है जो निजी डेटा सदस्यों बदल रहे हैं प्रभावित हैं की संख्या शामिल है।

जो कुछ भी बहुत अधिक बताता है, और यह मेरी राय में भी काफी उचित है।

0

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

उदाहरण में आप उद्धरण देते हैं, प्रेरणा एक और प्रकार का है: कम से कम युग्मित डिज़ाइन का उपयोग करें जो आपको अभी भी नौकरी करने की अनुमति देता है।

इसका मतलब है कि clearEverything जबकि (और, स्पष्ट होने की संभावना होगी) सदस्य बनने के लिए, हम इसे एक नहीं बनाते क्योंकि यह तकनीकी रूप से नहीं होना चाहिए। यह आपको दो चीजें खरीदता है:

  1. आप अपनी सार्वजनिक इंटरफ़ेस में एक clearEverything विधि होने की जिम्मेदारी स्वीकार करने के लिए नहीं है (एक बार आप एक के साथ जहाज, आप 'फिर से जीवन के लिए यह करने के लिए शादी की)।
  2. कक्षा के private सदस्यों तक पहुंच के साथ कार्यों की संख्या एक कम है, इसलिए भविष्य में कोई भी बदलाव करना आसान होगा और बग का कारण बनने की संभावना कम होगी।

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

3

मैं अक्सर अपने वर्गों के बाहर उपयोगिता विधियों का निर्माण करना चुनता हूं जब वे एप्लिकेशन विशिष्ट होते हैं।

आवेदन आमतौर पर एक अलग संदर्भ में होता है, फिर इंजन नीचे काम कर रहे हैं। यदि हम आपको एक वेब ब्राउज़र का उदाहरण लेते हैं, तो 3 स्पष्ट विधियां वेब इंजन से संबंधित होती हैं क्योंकि यह आवश्यक कार्यक्षमता है जो कहीं और लागू करना मुश्किल होगा, हालांकि, ClearEverything() निश्चित रूप से अधिक एप्लिकेशन विशिष्ट है। इस उदाहरण में आपके एप्लिकेशन में एक छोटा सा संवाद हो सकता है जिसमें उपयोगकर्ता को अधिक कुशल होने में सहायता करने के लिए एक स्पष्ट बटन है। हो सकता है कि यह कुछ ऐसा नहीं है जो आपके वेब ब्राउजर इंजन का पुन: उपयोग कर रहा है और इंजन क्लास में इसे रखने के लिए और अधिक अव्यवस्था होगी।

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

मैं कभी भी एक या दूसरे तरीके से चीजों को लागू करने के लिए मजबूत हार्डकोड नियमों का बड़ा प्रशंसक नहीं रहा हूं, यह अक्सर विचारधारा और सिद्धांतों का विषय है।

एम

0

इलाका और वर्ग जबकि कैप्सूलीकरण को बनाए रखने के 'पर्याप्त' सुविधाओं को देने की अनुमति कुछ तथ्यों पर गौर करने के लिए कर रहे हैं।

यदि WebBrowser कई स्थानों पर पुन: उपयोग किया जाता है, तो निर्भरता/ग्राहक कई सुविधा कार्यों को परिभाषित कर सकते हैं। यह आपके वर्ग (WebBrowser) हल्के और प्रबंधित करने में आसान रखता है।

उलटा यह होगा कि WebBrowser सभी ग्राहकों को प्रसन्न करने के लिए समाप्त होता है, और केवल कुछ मोनोलिथिक जानवर बन जाता है जिसे बदलना मुश्किल होता है।

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

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

मामलों वहाँ भी हो जाएगा जहां आप कुछ एहसास वास्तव में WebBrowser से लापता है के रूप में आप इसे उपयोग।

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