C ++ मित्र को या मित्र को नहीं


19

मेरे पास कॉलेज में इस सेमेस्टर में c ++ कोर्स के साथ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग है और हम फ्रेंड फंक्शन के बारे में सीख रहे थे।

मैं सहजता से उन्हें नापसंद करने की उनकी क्षमता के लिए नापसंद करता हूं जो एनकैप्सुलेशन और डेटा छिपाना प्रदान करते हैं, मैंने इंटरनेट पर कुछ लेख पढ़े और कुछ लोगों ने सोचा कि यह कुछ वैध उपयोगों के साथ एक अच्छा विचार था।

C ++ में मित्र fucntions के बारे में एक OOPs विशेषज्ञ क्या कहेंगे? क्या मुझे इसके बारे में अधिक जानकारी देनी चाहिए या मुझे इसके बारे में और सीखना चाहिए?


@all: बहुत बढ़िया जवाब और टिप्पणियाँ, यह सीखने का एक बहुत अच्छा तरीका है, मेरे पास पाठ्यपुस्तक में ऐसे विवरणों में दोस्तों के बारे में कोई तरीका नहीं है।
निखिल

जवाबों:


13

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

 double a;
 Vector v, w;
 w = v * a;

हम एक सदस्य समारोह के साथ ऐसा कर सकते हैं:

public class Vector {
 ...
 Vector operator*(double a);
}

लेकिन हम यह भी लिखना चाहेंगे:

w = a * v

इसके लिए नि: शुल्क फ़ंक्शन की आवश्यकता होती है:

 Vector operator*(double a, Vector v)

friendकीवर्ड सी में जोड़ा गया था ++ इस प्रयोग का समर्थन करने के। नि: शुल्क फ़ंक्शन वेक्टर क्लास कार्यान्वयन का हिस्सा है, और इसे उसी हेडर में घोषित किया जाना चाहिए और उसी स्रोत फ़ाइल में लागू किया जाना चाहिए।

इसी तरह हम friendएक संग्रह और एक पुनरावृत्तिकर्ता की तरह कसकर युग्मित वर्गों के कार्यान्वयन को सरल बनाने के लिए उपयोग कर सकते हैं । फिर से, मैं दोनों वर्गों को एक ही हेडर में घोषित करूँगा, और उन्हें एक ही स्रोत फ़ाइल में लागू करूँगा।


3
"इसके लिए नि: शुल्क फ़ंक्शन की आवश्यकता है"। नहीं, यह नहीं है inline Vector operator*(double a, Vector v) { return v*a; }:। वास्तव में विहित समाधान।
एमएसलटर्स

1
@ दलाल: अच्छी बात है। मैंने एक खराब उदाहरण उठाया। मुझे लगता है कि आपका इनलाइन फ़ंक्शन परिभाषा द्वारा एक नि: शुल्क फ़ंक्शन है, लेकिन किसी भी दोस्त की घोषणा की आवश्यकता नहीं है।
केविन क्लाइन

4
@MSalters: यह केवल तभी मान्य है जब * a और v (x) के लिए सराहनीय सम्मान है। यदि वेक्टर घटक जेनेरिक हैं (जरूरी नहीं कि स्कैलर्स) तो आपको ऑपरेंड ऑर्डर रखना होगा
एमिलियो गरवाग्लिया

यह बहुत सैद्धांतिक है। शायद एकमात्र सामान्य गैर-कम्यूटेटिव मामला होगा inline Vector operator*(double a, Vector v) { return -v*a; }और अभी भी दोस्ती की आवश्यकता नहीं है।
मलयाल्ट्स जूल 26'15

16

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

यह friendएक एकल फ़ंक्शन से बेहतर है कि आप ऐसा कुछ करने के लिए मजबूर हों, जिसे आप सार्वजनिक नहीं करना चाहते हैं। इसका मतलब है कि पूरी दुनिया इसका उपयोग कर सकती है- बजाय केवल एक फ़ंक्शन के।


मित्र कार्यों के लिए +1 एन्कैप्सुलेशन के संदर्भ में सदस्य कार्यों के लिए अलग नहीं है। यह केवल सार्वजनिक सदस्य कार्यों के लिए सही है।
TheFogger

1
@ TheFogger: संभवतः, आप friendएक फ़ंक्शन भी "निजी" कर सकते हैं, जैसे कि केवल एक ही TU में घोषित किया गया है।
डेडएमजी सेप

5

यदि आप इस बारे में भावुक हैं कि आप क्या करते हैं, तो आप C ++ के बारे में सब कुछ सीख रहे होंगे। जानें कि वे किस चीज के लिए उपयोग किए जाते हैं, उनका उपयोग कैसे करें, और फिर - और उसके बाद ही - उनका उपयोग न करने का निर्णय लें। बहुत कम से कम, आप किसी और के कोड को पढ़ते समय तैयार होंगे जो C ++ के इस पहलू का उपयोग करता है।


5

" एक OOPs विशेषज्ञ क्या कहेंगे ... " यह ज्यादातर इस बात पर निर्भर करता है कि वह C ++ में किस तरह का विशेषज्ञ है, जिससे उसका अपना विनिर्देशन है - और वह शुद्धिकरण के लिए भाषा नहीं है।

OOP के आवारा लोग C ++ का उपयोग नहीं करते (वे स्मॉलटाकल पसंद करते हैं, और जावा की तरह)।

कार्यात्मक प्रोग्रामिंग zelots C ++ का उपयोग नहीं करते (वे LISP पसंद करते हैं, और इसके उत्तराधिकारी)

OOP के अधिकांश विशेषज्ञ फ्रेंड फंक्शन को नापसंद करते हैं क्योंकि वे चाहते हैं कि C ++ का OOP हिस्सा स्मॉलटाक की तरह व्यवहार करे। लेकिन C ++ स्मालटाक नहीं है, और वे यह भी नहीं समझ सकते हैं कि दोस्त बहुत ही सरल कारण से यह समझ नहीं पा रहे हैं कि कोई फ़ंक्शन आपके वर्ग का दोस्त नहीं हो सकता है, क्योंकि आपकी कक्षा ऐसा नहीं चाहती है

और "कार्यक्षमता" स्टैंड बिंदु से, के बीच a.fn(b)और fn(a,b)कोई अंतर नहीं है (जहां fnएक दोस्त है): शामिल पार्टियां समान हैं। बस, एक वाक्यविन्यास किसी अन्य की तुलना में अधिक उपयुक्त हो सकता है: यदि fn के बारे में कम्यूटेटिव है aऔर b, fn(a,b)शायद अधिक उपयुक्त है a.fn(b)(जहां "एक विशेष भूमिका" वाला दिखता है, वास्तव में, यह नहीं है।)


1
"OOP zealots" जो जावा को पसंद करते हैं, उन्होंने OOP को नहीं समझा है। Getters? Setters? बंद करने के लिए कोई सरल वाक्यविन्यास? एलन के को पैराफेयर करने के लिए, इस तरह से उन्होंने OOP की कल्पना नहीं की।
कोनराड रुडोल्फ

@Konrad: zealots बेहतर असीमित सेट हैं। किसी दिए गए युग्मक की तुलना में हमेशा एक zealot अधिक zealot होता है।
एमिलियो गरवाग्लिया

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

5

क्या "दोस्त" इनकैप्सुलेशन का उल्लंघन करता है?

नहीं, यह नहीं है। "मित्र" सदस्यता की तरह ही पहुंच प्रदान करने का एक स्पष्ट तंत्र है। आप एक (मानक अनुरूप कार्यक्रम में) अपने स्रोत को संशोधित किए बिना खुद को एक वर्ग तक पहुंच प्रदान नहीं कर सकते।


2

सी ++ पूछे जाने वाले प्रश्न संक्षिप्त है:

जब आप कर सकते हैं एक सदस्य का उपयोग करें, और एक दोस्त जब आप के लिए है।

एफएक्यू दोस्ती के बारे में सोचने के अधिक उपयोगी तरीकों में से एक प्रस्तुत करता है:

बहुत से लोग फ्रेंड फंक्शन को क्लास के बाहर की चीज समझते हैं। इसके बजाय, क्लास के पब्लिक इंटरफेस के हिस्से के रूप में एक फ्रेंड फंक्शन के बारे में सोचें। कक्षा की घोषणा में एक मित्र कार्य किसी सार्वजनिक सदस्य फ़ंक्शन के उल्लंघन से किसी भी अधिक एनकैप्सुलेशन का उल्लंघन नहीं करता है: दोनों के पास क्लास के गैर-सार्वजनिक भागों तक पहुँचने के संबंध में एक ही प्राधिकरण है।

शायद दोस्त के कार्यों का सबसे आम उपयोग ओवरलोडिंग है << I / O के लिए।


0

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

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


-2

C ++ मित्र फ़ंक्शन निम्न कार्यक्षमता से निकटता से संबंधित हैं:

  1. मुक्त कार्य
  2. स्थिर कार्य
  3. मित्र कार्य करता है

इसका मतलब है कि उनके पास यह-सूचक नहीं है और इस प्रकार वर्ग / वस्तु के बाहर हैं। दूसरी ओर, वे अक्सर ऐसे पैरामीटर लेते हैं जो उन्हें फिर से कक्षा से संबंधित बनाते हैं। यहां कुछ उदाहरण दिए गए हैं जो लिंक को स्पष्ट करते हैं:

class B;
class A {
public:
    friend void f(A &a, B &b);
private:
    int m_a;
};
class B {
public:
   friend void f(A &a, B &b);
private:
   int m_b;
};
void f(A &a, B &b) { /* uses both A's and B's private data */ }

स्थिर कार्यों और मित्र कार्यों के बीच एकमात्र अंतर यह है कि एक मित्र फ़ंक्शन कई वर्गों का उपयोग कर सकता है।

C ++ में मित्र तंत्र का उपयोग करने के लिए प्रोग्रामर की आवश्यकता होती है, जिनके पास प्रोग्रामिंग के c ++ तरीके के साथ लगभग 10-15 वर्ष का अनुभव होता है, और इस प्रकार शुरू में आपको इससे बचना चाहिए। यह उन्नत सुविधा है।


7
और आपने 10-15 साल कैसे निकाले?
डेडएमजी सेप

10-15 साल उस समय से आता है जब यह पहली बार वास्तव में आवश्यक हो जाता है।
tp1 12

3
तो आपने मनमाने ढंग से एक नंबर बनाया, फिर।
डेडएमजी सेप

3
-1: "आपको इससे बचना चाहिए।" C ++ की हर सुविधा एक समस्या को हल करने के लिए बनाई गई थी। जब वह समस्या उत्पन्न होती है, तो उपयुक्त सुविधा का उपयोग करें।
केविन क्लाइन

-1 के लिए धन्यवाद। उस टिप्पणी का एक कारण था। लगता है कि यह सिर्फ कठिन अवधारणा है कि सभी सुविधाएँ शुरुआती के लिए उपयुक्त नहीं हैं।
tp1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.