2012-10-10 21 views
5

पुस्तक में सी ++ प्रोग्रामिंग भाषा, बजेर्न स्ट्राउस्ट्रप द्वारा, लेखक एक क्लास मैट्रिक्स पेश करता है जिसे फ़ंक्शन इन() को कार्यान्वित करना होता है। धारा 11.5.1 में, वह से बात करने की दो संभावनाओं के बारे में बात करता है। एक सदस्य फ़ंक्शन बनाना है और अन्य पर एक मित्र फ़ंक्शन inv() बनाना है। तो खंड 11.5.2, वह जहां बात करती है के बारे में कि क्या एक दोस्त या एक सदस्य समारोह का उपयोग करने के विकल्प बन के अंत में, वे कहते हैं:फ़ंक्शन को ऑब्जेक्ट की स्थिति बदलने के लिए किसी सदस्य फ़ंक्शन या मित्र फ़ंक्शन के लिए जाना है या नहीं?

तो निवेश संबंधी निर्णय निर्माताओं() की विपरीत मैट्रिक्स मीटर वास्तव में करता ही है, बल्कि एक नया मैट्रिक्स लौटने से पहले एम के विपरीत है, यह एक सदस्य होना चाहिए।

ऐसा क्यों है? क्या कोई मित्र फ़ंक्शन मैट्रिक्स की स्थिति को बदल नहीं सकता है और उस मैट्रिक्स के संदर्भ को वापस कर सकता है? क्या हम फ़ंक्शन को कॉल करते समय एक अस्थायी मैट्रिक्स पास करने की संभावना के कारण हैं? ..

+1

शायद अलग-अलग मित्र कार्यों में फैलाने के बजाय ऑब्जेक्ट के अंदर कार्यक्षमता के अधिक स्पष्ट रूप से परिभाषित encapsulation के लिए। – PherricOxide

+2

संबंधित http://stackoverflow.com/a/7821482/46642 –

+0

मुझे लगता है कि यहां उपरोक्तों के योग्य उत्तर सदस्यों के कार्यों और गैर-सदस्य मित्रों के बीच वास्तविक अंतर बताते हैं और यह बताते हैं कि निर्णय लेने में ये मतभेद कैसे योगदान देंगे, नहीं सब कुछ दूर से लहरें "क्योंकि यह अधिक/कम encapsulation प्रदान करता है"। –

उत्तर

9

ईमानदार होने के लिए, मुझे लगता है कि ऐसा निर्णय लेने का एकमात्र कारण वाक्य रचनात्मक सुविधा और परंपरा है। मैं समझाऊंगा कि क्यों दिखा रहा है कि दोनों के बीच मतभेद क्या हैं (नहीं) और निर्णय लेने के दौरान ये अंतर कैसे मायने रखते हैं।

गैर-सदस्य मित्र कार्यों और सार्वजनिक सदस्य कार्यों के बीच क्या अंतर है? बहुत ज्यादा नहीं। आखिरकार, एक सदस्य फ़ंक्शन एक छिपी हुई this पैरामीटर और कक्षा के निजी सदस्यों तक पहुंच के साथ एक नियमित कार्य है।

// what is the difference between the two inv functions? 
// --- our code --- 
struct matrix1x1 { // this one is simple :P 
private: 
    double x; 
public: 
    //... blah blah 
    void inv() { x = 1/x; } 
    friend void inv(matrix1x1& self) { self.x = 1/self.x; } 
}; 
matrix1x1 a; 

// --- client code --- 

// pretty much just this: 
a.inv(); 
// vs this: 
inv(a); 

void lets_try_to_break_encapsulation(matrix1x1& thingy) { 
    thingy.x = 42; // oops, error. Nope, still encapsulated. 
} 

वे दोनों एक ही कार्यक्षमता प्रदान करते हैं, और वे किसी भी तरह से अन्य कार्यों को नहीं बदल सकते हैं। एक ही इंटर्नल बाहरी दुनिया से अवगत कराया जाता है: encapsulation के मामले में कोई अंतर नहीं है।बिल्कुल कुछ भी नहीं है कि अन्य कार्य अलग-अलग काम कर सकते हैं क्योंकि एक दोस्त का कार्य है जो निजी राज्य को संशोधित करता है।

वास्तव में, अधिकांश गैर-सदस्य मित्र कार्यों (वर्चुअल फ़ंक्शंस और कुछ अधिभारित ऑपरेटर सदस्य होना चाहिए) के रूप में अधिकांश कार्यों के साथ अधिकांश कक्षाएं लिख सकते हैं, सटीक समान मात्रा में इंकैप्यूलेशन प्रदान करते हैं: उपयोगकर्ता बिना किसी संशोधन के किसी अन्य मित्र फ़ंक्शन को लिख सकते हैं कक्षा, और मित्र कार्यों के अलावा कोई भी कार्य निजी सदस्यों तक पहुंच सकता है। हम ऐसा क्यों नहीं करते? क्योंकि यह 99.99% सी ++ प्रोग्रामर की शैली के खिलाफ होगा और इससे कोई फायदा नहीं होगा।

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

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

प्रश्न में विशेष उदाहरण को संबोधित करने के लिए, inv सदस्य या गैर-सदस्य होना चाहिए? मैं शायद उपरोक्त उल्लिखित पारिवारिक तर्क के लिए इसे एक सदस्य बना दूंगा। गैर-स्टाइलिस्टिक रूप से, इससे कोई फर्क नहीं पड़ता है।


। यह सी ++ में होने की संभावना नहीं है क्योंकि इस बिंदु पर यह कोई बड़ा लाभ नहीं होने के कारण एक तोड़ने वाला परिवर्तन होगा। यह एक चरम उदाहरण के लिए, ऊपर लिखा गया matrix1x1 वर्ग तोड़ देगा क्योंकि यह दोनों संदिग्ध कॉल करता है।

+0

आपने किसी मित्र फ़ंक्शन का एक निश्चित रूप से निहित मामला प्रदान किया है, लेकिन जब कोई क्लास को मित्र बनाता है तो क्या होता है? यह तर्क दिया जा सकता है कि यह वास्तव में कम करता है या यहां तक ​​कि encapsulation तोड़ देता है। – Brady

+0

प्रश्न के लायक होने के लिए सदस्य कार्य बनाम मित्र कार्यों के बारे में है (यह मित्र वर्गों के लिए बिल्कुल कोई समझ नहीं आता है)। यदि यह कक्षाओं के बारे में था तो मुझे अभी भी उस दावे को स्वीकार करने के लिए एक उदाहरण की आवश्यकता होगी। –

+0

अच्छा बिंदु। मेरा जवाब सामान्य रूप से दोस्तों (कक्षा और समारोह) का जिक्र कर रहा था। एसटीएल कई स्थानों पर मित्र कार्यों का उपयोग करता है, लेकिन मुझे नहीं लगता कि यह मित्र वर्गों का उपयोग करता है। – Brady

0

ओओडी (जो सी ++ प्रचार करने की कोशिश करता है) के निहित समावेशन दर्शन यह इंगित करता है कि ऑब्जेक्ट स्थिति केवल भीतर से संशोधित की जा सकती है। यह वाक्य रचनात्मक रूप से सही है (संकलक इसे अनुमति देता है) लेकिन इसे टालना चाहिए।

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

0

दो विरोधी मित्र का उपयोग कर के तर्क को कर रहे हैं:

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

दूसरी तरफ कहता है कि दोस्तों वास्तव में encapsulation बढ़ा सकते हैं, क्योंकि आप बाहरी इकाइयों के एक छोटे से सेट के लिए कक्षा के आंतरिक प्रवेश तक पहुंच सकते हैं, इस प्रकार आंतरिक कक्षाओं को सभी को सार्वजनिक रूप से विशेषता बनाने की आवश्यकता को रोकना ताकि इन बाहरी संस्थाएं उन्हें एक्सेस/हेरफेर कर सकते हैं।

दोनों पक्षों पर तर्क दिया जा सकता है, लेकिन मैं पहले विकल्प से सहमत हूं।

आपके प्रश्न के लिए, इसके रूप में फेरिकिकऑक्साइड ने अपनी टिप्पणी में उल्लेख किया है: यदि किसी वर्ग के आंतरिक गुणों को संशोधित करने की आवश्यकता है, तो यह बेहतर होगा कि सदस्य विधि द्वारा किया जाए, इस प्रकार encapsulation लागू किया जा सके। यह ऊपर वर्णित पहले विकल्प के साथ इनलाइन है।

+0

डाउनवोट क्यों ?? – Brady

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

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