Friend Function in C++: Friend Function एक ऐसा Function होता है जो किसी Class का Member नहीं होता है, लेकिन फिर भी Class के Private व Protected Data Members को Access कर सकता है।
सामान्यतया OOPS का नि;म ये है कि कोई भी Non-Member Function Class के Private व Protected Data को Access ना कर सके। लेकिन कुछ स्थितियों में Data Hiding के इस नि;म को तोडना पडता है ताकि कोई Non-Member Function भी Class के Private व Protected Data को Access कर सके। ये काम Friend Functions करते हैं।
ये स्थिति तब पैदा होती है जब हम किसी Non-Object को किसी Overloaded Operator के Left Side में Use करना चाहते हैं। Friend Functions का प्रयोग करने की दूसरी स्थिति तब पैदा होती है जब हम किसी Argument के रूप में Function Notation को किसी Object के साथ Use करते हैं।
TTime उदाहरण में हमने + Operator को Overload करके दो TTime Objects के मानों को जोडा था। वह Program अच्छी तरह से निम्नानुसार काम कर रहा था:
Time3 = Time2 + Time1;
मानलो कि एक Class Creator के रूप में हम ये चाहते हैं कि Class का User TTime Object के साथ निम्नानुसार प्रक्रिया भी कर सके:
TTime2 = TTime1 + 1;
यानी Time Object के hours की संख्या में कोई Integer मान जोड सके। जैसे:
4:10 + 6 = 10:10
जैसाकि उपरोक्त Statement में बताया गया है, यदि हम Operator के Right Side में किसी Integer का प्रयोग करते हैं, तो ये Statement आसानी से काम करता है। यदि TTime Class में एक 1-Argument Constructor हो तो Compiler Automatically इसका प्रयोग Integer मान को TTime Object मान में Convert करने के लिए कर लेता है और फिर उस मान को TTime Object के hours के मान में जोड देता है।
// overloads the + operator for TTime class, // integer cannot be used for on left of operator #include <iostream.h> #include <conio.h> class TTime { private: int hours; // 0 to 23 int minutes; // 0 to 59 public: // 0, 1 or 2 arg constructor TTime(int h = 0, int m = 0) : hours(h), minutes(m) { } void display() // output to screen { cout << hours << ':' << minutes; } void get() // input from user { char dummy; cin >> hours >> dummy >> minutes; } // overloaded + operator TTime operator + (TTime right) { TTime temp; // make a temporary object temp.hours = hours + right.hours; // add data temp.minutes = minutes + right.minutes; if(temp.minutes >= 60) // check for carry { temp.hours++; temp.minutes -= 60; } return temp; // return temporary object by value } }; // end class TTime void main() { TTime Time1, Time2; cout << “Enter an TTime: "; Time1.get(); Time2 = Time1 + 1; // add integer to TTime cout << “TTime + 1 = "; Time2.display(); // display sum // Time2 = 1 + Time1; // error: illegal structure operation getch(); }
इस Program का Constructor तीन स्थितियों को Handle करता है: No-Argument, 1-Arguments व 2-Arguments, हम चाहें तो तीन Separate Constructors का प्रयोग कर सकते हैं।
एक 1-Argument Constructor के रूप में Compiler इसका प्रयोग मान 1 को main() Function में TTime(1,0) मान में Convert करने के लिए करता है, जो कि बाद में Time1 Object के मान में जोड दिया जाता है। इस Program का Output कुछ निम्नानुसार होता है:
Enter an TTime: 6:15
TTime + 1 = 7:15
Operator+() Function को Constructor की थोडी सी मदद से + Operator के Right Side के एक Integer मान को Time Object में Add करने में यहां कोई परेशानी नहीं होती है।
main() Function में Program की Last Line Commented Line में हम देख सकते हैं कि यदि हम मान 1 को + Operator के Left Side में Place करके Add करने की कोशिश करते हैं, तो Compiler हमें Error देता है। यानी:
Time2 = 1 + Time1; // This Statement Makes Error
ये Statement इसलिए काम नहीं करता है क्योंकि Overloaded + Operator केवल एक Member Function है, जिसे Object के Left में Object द्वारा Call किया जाता है और Right Side का Object इस Function का Argument होता है। यानी हम निम्नStatement
Time2 = Time1 + 1
को निम्नानुसार भी लिख सकते हैं:
Time2 = Time1.operaor+(1);
ये Statement सामान्य रूप से काम करता है लेकिन यदि हम Argument को Left Side में निम्नानुसार लिखे:
Time2 = 1.operator+(Time1)
हम समझ सकते हैं कि ये Statement गलत है और हम ऐसा नहीं कर सकते हैं। Member Functions को केवल उसी Class का Object Invoke कर सकता है और मान 1 TTime Class का Object नहीं है, बल्कि एक Constant मान है, इसलिए ये operator+() Member Function को Call नहीं कर सकता है और हम किसी Overloaded Operator के Left Side में Constant मान का प्रयोग Object को जोडने के लिए नहीं कर सकते हैं।
इस समस्या के समाधान के लिए हमें Friend Function का प्रयोग करना ही होता है। Friend Functions को Class या Function से बाहर ठीक उसी तरह से Define किया जा सकता है, जैसे हम किसी Non-Member Global Function को Define करते हैं। इसका Class से Connection ये होता है कि Class के अन्दर इस Function को Friend Declare किया जाता है। इसे समझने के लिए निम्न उदाहरण देखें:
// Overloads + Operator for TTime class, // uses friend function to permit integer on left of + operator #include <iostream.h> #include <conio.h> class TTime { private: int hours; // 0 to 23 int minutes; // 0 to 59 public: // 0, 1, or 2 arg constructor TTime(int h = 0, int m = 0) : hours(h), minutes(m) { } void display() // output to screen { cout << hours << ':' << minutes; } void get() // input from user { char dummy; cin >> hours >> dummy >> minutes; } friend TTime operator+(TTime, TTime); // declaration }; // end class TTime // friend function: overloaded + operator TTime operator + (TTime left, TTime right) { TTime temp; // make a temporary object temp.hours = left.hours + right.hours; // add data temp.minutes = left.minutes + right.minutes; if(temp.minutes >= 60) // check for carry { temp.hours++; temp.minutes -= 60; } return temp; // return temporary object by value } void main() { TTime Time1, Time2; cout << “Enter an TTime: "; Time1.get(); Time2 = Time1 + 3; // add integer to TTime cout << “TTime + 3 = "; Time2.display(); // display sum Time2 = 3 + Time1; // add TTime to integer cout << “\n3 + TTime = "; Time2.display(); // display sum getch(); }
TTime Class में हमने निम्नानुसार एक अन्तिम Statement द्वारा एक Operator+() को friend Declare किया है:
friend TTime operator+(TTime, TTime);
हम Class में इस Declaration को कहीं भी यानी Public या Private किसी भी Part में Declare कर सकते हैं। हालांकि सैद्धांतिक रूप से इसे public Part में ही Declare करना चाहिए क्योंकि ये Class का एक public Interface है। Class को Use करने वाला कोई भी Class User Class के friend Function को Invoke कर सकता है। ये जरूरी नहीं है कि केवल उसी Class के Members friend Function को Access कर सकते हैं। इसलिए सामान्यतया friend Function के Declaration को Public Part में Declare किया जाता है।
जैसाकि हम देख सकते हैं, operator+()Function TTime Class का एक Member Function नहीं है। यदि ये TTime Class का Member Function होताए तो हमें इसे निम्नानुसार Declare करना पडता :
TTime TTime::operator + (TTime left, TTime right)
फिर भी, ये Function TTime Class के Private Data Members hours व minutes को Access कर सकता है। क्योंकि Class में इसे एक friend Function Declare किया गया है। operator+() Function दो Arguments लेता है, जिसे left व right नाम दिया गया है।
चूंकि ये एक Standalone Function है ना कि Class का Member Function, इसलिए इसे किसी Object द्वारा Invoke नहीं किया जा सकता है। इसे एक Global Function की तरह main() Function द्वारा Call किया जाता है और जिन दो Objects को आपस में जोडना है, उन्हें Arguments के रूप में इस Function में Pass किया जा सकता है।
एक साधारण नि;म के अनुसार किसी Function का friend Version हमेंशा एक साधारण Member Function की तुलना में एक Extra Argument लेता है। हालांकि दोनों Functions Internally समान होते हैं लेकिन एक friend Function TTime Arguments में friend Function Data को left.hours व right.hours से Refer करता है जबकि एक Member Function में Data को Refer करने के लिए hours व right.hours का प्रयोग होता है। friend Function दोनों Objects के मानों का जोड करता है और इस जोड को Return करता है।
यदि left या right दोनों में से कोई भी Argument एक Integer होता है, तो Compiler 1-Argument Constructor का प्रयोग करके इस Integer मान को TTime मान में Convert करता है और फिर उस मान को Object के मान में जोडता है। उदाहरण Program के main() Function में दोनों स्थितियों को देखा जा सकता है और Compiler दोनों स्थितियों को अब Handle कर लेता है।
जब C++ को Develop किया जा रहा था तब Friend Functions को Use करना OOPS के Concept के खिलाफ हो रहा था। यानी OOPS के नि;म इस प्रकार के Functions से Break होते थे। friend Functions Program में Extra Flexibility प्रदान कर रहे थे इसलिए इन्हें छोडा भी नहीं जा सकता था। जबकि ये इस नि;म का उल्लंघन करता था कि किसी Class के Data को केवल उसी Class के Objects ही Access कर सकते थे।
Friend Function को उस Class में Declare किया जाता है जिसके Data को Friend Function Access करना चाहता है। परिणामस्वरूप एक Programmer का वह Function, जो कि Class के Data को Access नहीं कर सकता है, उसे Friend Function में Convert नहीं किया जा सकता है। इस स्थिति में Class के Data तब भी सुरिक्षत रहते हैं।
आज की सोंच ये है कि Friend Functions OOPS के नि;मों का इतना उल्लंघन नहीं करते हैं, कि Data को किसी प्रकार का नुकसान हो। जबकि C++ के Development के समय इसे OOPS के नि;मों को Break करने वाला Serious Concept माना जाता था और पुरानी मान्यता के अनुसार Data को नुकसान पहुंचा सकता था।
लेकिन फिर भी हमारी मान्यता ये है कि जहां तक सम्भव हो सके Friend Functions के स्थान पर Member Functions का ही प्रयोग करना चाहिए] क्योंकि Friend Functions काफी अजीब होते हैं और यदि कई friend Functions हों, तो Class की Boundary तय करना मुश्किल हो जाता है।
कई बार friend Functions हमें किसी Function को Call करने के लिए Member Functions की तुलना में ज्यादा स्पष्ट Calling Syntax प्रदान करते हैं। उदाहरण के लिए, मानलो कि हम एक ऐसा Function बनाना चाहते हैं जो English Class के Object का Square प्रदान करता है और हमें float प्रकार के मान के रूप में Square Feet प्रदान करता है। निम्न उदाहरण में बताया जा रहा है कि हम इस काम को कैसे कर सकते हैं:
// Program // member square() function for Distance #include <iostream.h> #include <conio.h> class English // English class { private: int feet; float inches; public: English(int ft, float in) // 2-arg constructor { feet = ft; inches = in; } void showdist() // display { cout << feet << “\'-” << inches << '\”'; } float square(); // member function declaration }; float English::square() // return square of { // this English object float fltfeet = feet + inches/12; // convert to float float feetsqrd = fltfeet * fltfeet; // find the square return feetsqrd; // return square feet } void main() { English dist(3, 6.0); // 1-arg constructor (3'-6") float sqft = dist.square(); // return square of dist // display distance and square cout << "\nDistance = "; dist.showdist(); cout << "\nSquare = " << sqft << " square feet"; } // Output Distance = 3’-6” Square = 12.25 square feet
इस Program का main() Function एक English Distance Value Create करता है, उसका Square करता है और Output में Results को Print कर देता है। किसी वर्ग का Area ज्ञात करने के लिए हमने इस Program में निम्न Statement का प्रयोग किया है:
sqft = dist.sqare();
ये Statement dist का square ज्ञात करता है और Result को sqft में Assign कर देता है। लेकिन यदि हम English Class Object के साथ इसी Statement द्वारा प्रक्रिया करना चाहें, जो कि सामान्य Numbers के साथ Use किया जा सके, तो हमें निम्नानुसार Function Notation को Use करना पडता है&
float sqft = square(dist);
हम इस Effect को English Class के sqare() Function को friend Function में Change करके प्राप्त कर सकते हैं। इसका Program निम्नानुसार है:
// friend square() function for English class #include <iostream.h> #include <conio.h> class English // English class { private: int feet; float inches; public: English(int ft, float in) // 2-arg constructor { feet = ft; inches = in; } void showdist() // display { cout << feet << "\'-" << inches << '\"'; } friend float square(English); // friend function }; float square(English d) // return square of { // the argument float fltfeet = d.feet + d.inches/12; // convert to float float feetsqrd = fltfeet * fltfeet; // find the square return feetsqrd; // return square feet } void main() { English dist(3, 6.0); // two-arg constructor (3'-6") float sqft = square(dist); // return square of dist // display distance and square cout << "\nDistance = "; dist.showdist(); cout << "\nSquare = " << sqft << " square feet"; getch(); }
अब हम उपरोक्त Statement को निम्नानुसार Use कर सकते हैं:
float sqft = square(dist);
हालांकि एक Member Function की तरह square() Function कोई Argument नहीं लेता है लेकिन friend Function की तरह ये एक Argument लेता है, जैसाकि हम इस उदाहरण में देख सकते हैं।
चलिए, एक और स्थिति देखते हैं जिसमें Friend Function का प्रयोग करना उचित होता है। मानलो कि हम एक ऐसा Function Develop करना चाहते हैं जो दो अलग Class के Objects पर Operate हो सके। इसके लिए Function दोनों Classes के Objects को Arguments के रूप में प्राप्त कर सकता है और उनके Private Data पर Operation Perform कर सकता है।
यदि दो Classes को एक ही Base Class से Derived किया गया है, तो हम Function को Base Class में रख सकते हैं। लेकिन जब Classes Unrelated हों तब हमें ऐसा करने के लिए friend Functions का प्रयोग करना पडेगा। इस Concept को निम्न Program द्वारा Implement किया गया है:
// friend functions #include <iostream.h> #include <conio.h> class beta; // needed for frifunc declaration class alpha { private: int data; public: alpha() { data = 3; } // no-arg constructor friend int frifunc(alpha, beta); // friend function }; class beta { private: int data; public: beta() { data = 7; } // no-arg constructor friend int frifunc(alpha, beta); // friend function }; int frifunc(alpha a, beta b) // function definition { return( a.data + b.data ); } void main() { alpha aa; beta bb; cout << frifunc(aa, bb); // call the function getch(); }
इस Program में दो Classes alpha व beta हैं। इन Classes के Constructors इनके Objects के एक Single Data Item को एक & एक Constant मान 3 व 7 से Initialize कर देता है। हम चाहते हैं कि frifunc() Function से दोनों Classes के Private Data Members को Access किया जा सके, इसलिए हमने इस Function को दोनों Classes में friend Keyword के साथ निम्नानुसार Declare किया है:
friend int frifunc(alpha, beta);
दोनों Classes के एक Object को Argument के रूप में इस Function में Pass किया गया है। frifunc() Function दोनों Classes के Private Data Members को इन Arguments के द्वारा Access कर लेता है। ये Function कुछ ज्यादा काम नहीं करता है। ये Data Items के मानों को जोडता है और परिणाम को Return करता है। main() Function इस Function को Call करता है और परिणाम को Print करता है। (Friend Function in C++ – ProgramIZ)
एक बात हमेंशा ध्यान रखें कि एक Class तब तक दूसरी Class को Refer नहीं कर सकता है जब तक कि उसे Declare ना किया जाए। चूंकि frifunc() Function के Declaration में Class beta को Class alpha में Refer किया गया है, इसलिए beta को alpha से पहले निम्न Statement द्वारा Program की शुरूआत मे Declare किया गया है:
Class beta;
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C++ Programming Language in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C++ Programming Language in Hindi | Page: 666 | Format: PDF