Theory
Auditor की problem
College canteen की books verify करने के लिए एक auditor भेजता है। Till का cash private है, बिल्कुल जैसा होना चाहिए।
पर auditor CanteenTill का एक member function नहीं है: audits को उस class के बाहर रहना चाहिए जिसे वे inspect करते हैं, वरना inspection का कोई मतलब नहीं।
तो सवाल: एक बाहरी function cash को पूरी दुनिया के लिए cash को public बनाए बिना कैसे पढ़े? C++ एक keyword से जवाब देता है जो friendly लगता है और एक signed gate pass की तरह काम करता है: friend।
Theory
Gate pass
Owner एक note लिखता है और office के अंदर pin करता है: "Auditor Mr. Desai cash drawer खोल सकते हैं।"
तीन चीज़ें notice कीजिए: owner ने pass issue किया (auditor ने माँगा नहीं), pass एक व्यक्ति का नाम लेता है (सारे visitors का नहीं), और Mr. Desai अभी भी बाहर काम करते हैं: pass उन्हें staff नहीं बनाता।
यही एक friend declaration है: एक named outsider को class द्वारा दी गई access, जो outsider ही रहता है।
Theory
Friend function, formally
एक friend function एक non-member function है जिसे एक class अपने private और protected members तक access के लिए authorize करती है।
- Class के अंदर
friendkeyword से declared। - बाहर एक normal function जैसा defined: definition में कोई
ClassName::prefix नहीं, कोईfriendkeyword नहीं। - dot operator से call नहीं होता: यह object को parameter के रूप में लेता है और उसके अंदर पहुँचता है।
Declaration public या private section में कहीं भी रह सकती है; इसकी position कुछ नहीं बदलती।
Practical
Code में audit gate pass
#include <iostream>
using namespace std;
class CanteenTill {
private:
double cash;
public:
CanteenTill(double opening) { cash = opening; }
// the gate pass: audit() may read private members
friend void audit(CanteenTill t);
};
// defined outside: no CanteenTill::, no friend keyword here
void audit(CanteenTill t) {
cout << "Audited balance: " << t.cash << endl; // legal: friend
}
int main() {
CanteenTill till(500.0);
audit(till); // ordinary call, NOT till.audit()
return 0;
}
Think first
Member या नहीं?
Declaration friend void audit(CanteenTill t); class body के अंदर बैठी है। tap करने से पहले: क्या audit() CanteenTill का एक member function है? और main() इसे कैसे call करेगा: audit(till) या till.audit()?
Show the answer
Member नहीं। friend keyword इसे एक outsider के रूप में mark करता है जिसे access दी गई है; class body के अंदर लिखा होना सिर्फ़ वह जगह है जहाँ grant record हुआ। इसलिए main() इसे एक ordinary function के रूप में call करता है: audit(till)। till.audit() लिखना एक compile error है, और "अंदर declared, फिर भी member नहीं" exam का favourite friend-function trick है।
Quiz
audit() CanteenTill का एक friend है। StaffTill, CanteenTill से derived है। क्या audit() StaffTill के अपने private members access कर सकता है?
- नहीं: friendship derived classes द्वारा inherit नहीं होती
- हाँ: base के friends हर child के friends होते हैं
- हाँ, पर सिर्फ़ protected members
- सिर्फ़ तभी अगर StaffTill उसी file में है
Show the answer
नहीं: friendship derived classes द्वारा inherit नहीं होती
Friendship उस class के लिए personal है जिसने इसे grant किया: यह inherit नहीं होती, mutual नहीं है, और transitive नहीं है। StaffTill को अपनी friend declaration ख़ुद issue करनी होगी। (audit() फिर भी एक StaffTill object के अंदर inherited CanteenTill-part तक पहुँच सकता है, पर StaffTill के अपने private additions बंद रहते हैं।) Option B misconception है; file placement access को कभी affect नहीं करती।
Watch out
सावधानी से handle कीजिए
हर friend function encapsulation में drilled एक छोटा hole है। Exams चाहते हैं आप यह कहें: "friend functions को sparingly इस्तेमाल करना चाहिए क्योंकि वे data hiding bypass करते हैं।"
Definitions में भी precise रहिए: friendship class द्वारा उसकी अपनी body में grant की जाती है। एक function बाहर से ख़ुद को friend declare नहीं कर सकता, वरना private का कोई मतलब नहीं रहता।
Theory
जब friend सही tool है
Honest use case: एक operation जिसे एक साथ दो अलग classes का private data चाहिए, जैसे एक CanteenTill के cash की एक BankRecord की entry से comparison। दोनों classes उस function का natural घर नहीं हैं, तो दोनों इसे friend declare करती हैं। Operator overloading भी friends पर टिकता है (cout << till को private members पढ़ने देना)। एक function, दो gate passes: पूरी तरह legal।
Summary
Key takeaways
- एक friend function एक NON-member है जिसे private/protected members तक access दी गई है।
- Class के अंदर friend से declared; बाहर बिना :: और बिना friend keyword के defined।
- एक ordinary function की तरह call होता है, object parameter के रूप में, कभी dot से नहीं।
- Friendship class द्वारा grant होती है; यह inherit नहीं होती, mutual नहीं, transitive नहीं।
- Sparingly इस्तेमाल कीजिए: हर friend data hiding bypass करता है।
- Classic use: एक function जिसे दो classes के privates चाहिए; operator overloading।
- Memory hook: एक gate pass, staff badge नहीं।