Theory
તપાસનીસની સમસ્યા
College canteen ના ચોપડા ચકાસવા તપાસનીસ મોકલે છે. Till નો cash એ private છે, બરાબર જેમ હોવો જોઈએ તેમ.
પણ તપાસનીસ એ CanteenTill નું member function નથી: તપાસ જે class ને તપાસે એની બહાર જ રહેવી જોઈએ, નહીં તો તપાસનો કોઈ અર્થ નથી.
એટલે પ્રશ્ન: આખા જગત માટે cash ને public કર્યા વગર બહારનું function એને કેવી રીતે વાંચે? C++ એવા શબ્દથી જવાબ આપે છે જે મૈત્રીપૂર્ણ લાગે છે અને સહી કરેલા દરવાજાના પાસ જેવું વર્તે છે: friend.
Theory
દરવાજાનો પાસ
માલિક એક ચિઠ્ઠી લખીને કચેરીમાં લગાવે છે: "તપાસનીસ શ્રી દેસાઈ રોકડનું ખાનું ખોલી શકે છે."
ત્રણ વસ્તુ નોંધો: પાસ માલિકે આપ્યો છે (તપાસનીસે માંગ્યો નથી), પાસમાં એક જ વ્યક્તિ નું નામ છે (બધા મુલાકાતીઓનું નહીં), અને શ્રી દેસાઈ હજી canteen ની બહાર જ કામ કરે છે: પાસ એમને કર્મચારી બનાવતો નથી.
એ જ છે friend declaration: class દ્વારા અપાયેલી પહોંચ, નામ આપેલા બહારના માણસને, જે બહારનો જ રહે છે.
Theory
Friend function, ઔપચારિક રીતે
Friend function એ member ન હોય એવું function છે જેને class પોતાના private અને protected members સુધી પહોંચવાની સત્તા આપે છે.
- Class ની અંદર
friendશબ્દ સાથે declare થાય છે. - બહાર સામાન્ય function ની જેમ વ્યાખ્યાયિત થાય છે:
ClassName::ઉપસર્ગ નહીં, વ્યાખ્યા વખતેfriendશબ્દ નહીં. - ટપકાના operator થી બોલાવાતું નથી: એ object ને parameter તરીકે લે છે અને એની અંદર પહોંચે છે.
Declaration public કે private વિભાગમાં ગમે ત્યાં હોઈ શકે; એની જગ્યાથી કશું બદલાતું નથી.
Practical
તપાસનો દરવાજાનો પાસ code માં
#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 કે નહીં?
friend void audit(CanteenTill t); એ declaration class ના શરીરની અંદર છે. Tap કરતાં પહેલાં: audit() એ CanteenTill નું member function છે? અને main() એને કેવી રીતે બોલાવે: audit(till) કે till.audit()?
Show the answer
Member નથી. friend શબ્દ એને પહોંચ અપાયેલા બહારના માણસ તરીકે ચીંધે છે; class ના શરીરની અંદર લખાવું એ ફક્ત એ જગ્યા છે જ્યાં આ સત્તા નોંધાય છે. એટલે main() એને સામાન્ય function ની જેમ બોલાવે છે: audit(till). till.audit() લખવું એ compile ની ભૂલ છે, અને "અંદર declare થયેલું, છતાં member નહીં" એ બરાબર પરીક્ષાની friend function ની પ્રિય ચાલાકી છે.
Quiz
audit() એ CanteenTill નું friend છે. StaffTill એ CanteenTill માંથી derived છે. શું audit() એ StaffTill ના પોતાના private members સુધી પહોંચી શકે?
- ના: મિત્રતા derived classes ને વારસામાં મળતી નથી
- હા: base ના મિત્રો દરેક સંતાનના મિત્રો છે
- હા, પણ ફક્ત protected members સુધી
- ફક્ત જો StaffTill એ જ file માં હોય તો
Show the answer
ના: મિત્રતા derived classes ને વારસામાં મળતી નથી
મિત્રતા એ સત્તા આપનારા class પૂરતી અંગત છે: એ વારસામાં મળતી નથી, પરસ્પર નથી, અને સંક્રમક નથી. StaffTill એ પોતાનું friend declaration આપવું પડે. (audit() હજી StaffTill ના object ની અંદર વારસામાં આવેલા CanteenTill ના ભાગ સુધી પહોંચી શકે, પણ StaffTill ના પોતાના private ઉમેરા બંધ જ રહે છે.) વિકલ્પ B એ ગેરસમજ છે; file ની જગ્યા પહોંચને ક્યારેય અસર કરતી નથી.
Watch out
સંભાળીને વાપરો
દરેક friend function એ encapsulation માં પાડેલું નાનું કાણું છે. પરીક્ષાઓ તમારી પાસે એ કહેવડાવવા માંગે છે: "friend functions ઓછાં વાપરવાં જોઈએ કારણ કે એ data hiding ને બાજુ પર મૂકે છે."
વ્યાખ્યાઓમાં ચોકસાઈ પણ રાખો: મિત્રતા class પોતાના શરીરમાં આપે છે. Function પોતાની જાતને બહારથી મિત્ર જાહેર કરી શકતું નથી, નહીં તો private નો કોઈ અર્થ જ ન રહે.
Theory
Friend ક્યારે સાચું ઓજાર છે
પ્રામાણિક ઉપયોગ: એવી ક્રિયા જેને એકસાથે બે જુદા classes ના private data જોઈએ, જેમ કે CanteenTill ની cash ને BankRecord ની નોંધ સાથે સરખાવવી. એકેય class એ function નું સ્વાભાવિક ઘર નથી, એટલે બંને એને friend જાહેર કરે છે. Operator overloading પણ friends પર ટેકે છે (cout << till ને private members વંચાવવા). એક function, બે દરવાજાના પાસ: સાવ કાયદેસર.
Summary
Key takeaways
- Friend function એ member ન હોય એવું function છે જેને private/protected members સુધીની પહોંચ અપાય છે.
- Class ની અંદર friend સાથે declare થાય છે; બહાર :: વગર અને friend શબ્દ વગર વ્યાખ્યાયિત થાય છે.
- Object ને parameter તરીકે લઈને સામાન્ય function ની જેમ બોલાવાય છે, ક્યારેય ટપકાથી નહીં.
- મિત્રતા class આપે છે; એ વારસામાં મળતી નથી, પરસ્પર નથી, સંક્રમક નથી.
- ઓછું વાપરો: દરેક friend એ data hiding ને બાજુ પર મૂકે છે.
- જાણીતો ઉપયોગ: એક function ને બે classes ના private જોઈએ; operator overloading.
- Memory hook: દરવાજાનો પાસ, કર્મચારીનું ઓળખપત્ર નહીં.