ईमानदार होने के लिए, मुझे लगता है कि ऐसा निर्णय लेने का एकमात्र कारण वाक्य रचनात्मक सुविधा और परंपरा है। मैं समझाऊंगा कि क्यों दिखा रहा है कि दोनों के बीच मतभेद क्या हैं (नहीं) और निर्णय लेने के दौरान ये अंतर कैसे मायने रखते हैं।
गैर-सदस्य मित्र कार्यों और सार्वजनिक सदस्य कार्यों के बीच क्या अंतर है? बहुत ज्यादा नहीं। आखिरकार, एक सदस्य फ़ंक्शन एक छिपी हुई 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
वर्ग तोड़ देगा क्योंकि यह दोनों संदिग्ध कॉल करता है।
शायद अलग-अलग मित्र कार्यों में फैलाने के बजाय ऑब्जेक्ट के अंदर कार्यक्षमता के अधिक स्पष्ट रूप से परिभाषित encapsulation के लिए। – PherricOxide
संबंधित http://stackoverflow.com/a/7821482/46642 –
मुझे लगता है कि यहां उपरोक्तों के योग्य उत्तर सदस्यों के कार्यों और गैर-सदस्य मित्रों के बीच वास्तविक अंतर बताते हैं और यह बताते हैं कि निर्णय लेने में ये मतभेद कैसे योगदान देंगे, नहीं सब कुछ दूर से लहरें "क्योंकि यह अधिक/कम encapsulation प्रदान करता है"। –