*this Object: सवाल ये पैदा होता है कि क्या एक Object स्वयं के Reference को Return कर सकता है। पिछले Program में जब हमें उस Object के Return Value की जरूरत थी जिसके Reference में operator Function को Call किया गया था, तब हमने निम्नानुसार Constructor Use किया था:
return TTime(hours, minutes);
जहां hours व minutes Object के स्वयं के Data हैं। ये Statement एक Temporary Object Create करता है जिसमें वही Data होता है जो स्वयं Object में होता है। चूंकि Data एक Temporary Object में होता है इसलिए इसे By Value Return करना पडता है।
जैसाकि हमने पहले भी कहा कि Compiler इतना समझदार होता है कि वह इस स्थिति में केवल एक ही Temporary Object Create करता है। इसलिए इसे Execute करना Efficient होता है। फिर भी यदि हम Object को By Reference Return करना चाहें, तो हमें किसी Temporary Object की जरूरत नहीं होती है।
स्वयं के Object के मान को By Reference Return करने के लिए हमें उस Object के एक Magic नाम जिसे *this कहते हैं, की जरूरत होती है। किसी भी Member Function में ये नाम उसी Object को Refer करता है, जिसके लिए या जिसके Reference में operator Function को Call किया गया होता है। यानी यदि हम main() Function में निम्नानुसार Statement लिखते हैं:
anObject.aFunction()
तो afunction() में *this Expression उसी Object anObject को ही Refer करता है, जिसे main() Function में Create किया गया है। *this Expression Invisible रूप में Compiler द्वारा Function में Pass किया जाता है।
इसलिए कोई Member Function हमेंशा ये जानता है कि वह उस Object को कैसे Refer कर सकता है जिसके Reference में उसे Call किया गया है और Member Function को ये जानकारी *this के कारण प्राप्त होती है।
*this को Use करने के लिए हमें Pointers के बारे में जानकारी होना जरूरी नहीं होता है। हम बिना Pointers की जानकारी के भी इसे Use कर सकते हैं। फिर भी यदि Pointers की जानकारी हो तो *this में उस Object का Address होता है, जिसके Reference में किसी Member Function को Call किया जाता है। *this स्वयं Object की तरह ही काम करता है यानी ये स्वयं Object को Represent करता है और हम इसके द्वारा भी उस Object को Access कर सकते हैं जिसके Reference में किसी Member Function को Call किया गया होता है।
यदि किसी Member Function को उसी Object को Return करना हो, जिसके Reference में उसे Call किया गया है, तो Member Function में केवल निम्न Statement लिखना होता है:
return *this;
चूंकि यहां Object By Reference Return होता है इसलिए Object की कोई Copy Create नहीं होती है। इसके आधार पर हम += Operator को फिर से निम्नानुसार Revisit कर सकते हैं:
//Program // overloads the += operator, uses *this #include <iostream.h> #include <conio.h> class TTime { private: int hours; // 0 to 23 int minutes; // 0 to 59 public: // no-arg constructor TTime() : hours(0), minutes(0) { } // 2-arg constructor TTime(int h, int m) : hours(h), minutes(m) { } void display() const // output to screen { cout << hours << ':' << minutes; } void get() // input from user { char dummy; cout << "\nEnter time (format 12:59): "; cin >> hours >> dummy >> minutes; } // overloaded += operator TTime& operator += (const TTime& right) { hours += right.hours; // add argument to us minutes += right.minutes; if(minutes >= 60) // check for carry { hours++; minutes -= 60; } return *this; // return by reference } }; // end class TTime void main() { TTime Time1, Time2, Time3; cout << "Enter first TTime: "; Time1.get(); cout << "Enter second TTime: "; Time2.get(); Time1 += Time2; // overloaded += operator // adds Time2 to Time1 cout << "\nTime1 += Time2 = "; Time1.display(); // display result Time3 = Time1 += Time2; // do it again, use return value cout << "\nTime3 = "; Time3.display(); // display result getch(); } //Output Enter first TTime: Enter time (format 12:59): 3:21 Enter second TTime: Enter time (format 12:59): 6:12 Time1 += Time2 = 9:33 Time3 = 15:45
इसी तरह से हम Increment Operator को भी निम्नानुसार Program द्वारा Revisit कर सकते हैं जिसमें *this का प्रयोग करके Object को By Reference Return किया गया है।
Program // overloads the ++ operator, prefix version uses *this #include <iostream.h> class TTime { private: int hours; // 0 to 23 int minutes; // 0 to 59 public: // no-arg constructor TTime() : hours(0), minutes(0) { } // 2-arg constructor TTime(int h, int m) : hours(h), minutes(m) { } void display() const // output to screen { cout << hours << ':' << minutes; } void get() // input from user { char dummy; cout << "\nEnter time (format 12:59): "; cin >> hours >> dummy >> minutes; } TTime& operator++ () // overloaded prefix ++ operator { ++minutes; if(minutes >= 60) { ++hours; minutes -= 60; } return *this; // return our object by reference } TTime operator++ (int) // overloaded postfix ++ operator { TTime temp(hours, minutes); // save original value ++minutes; // increment this object if(minutes >= 60) { ++hours; minutes -= 60; } return temp; // return old original value } }; // end class TTime void main() { TTime Time1, Time2; // make two TTimes Time1.get(); // get value for one Time2 = ++Time1; // increment (prefix) and assign cout << "\nTime2="; Time2.display(); // display assigned value Time2 = Time1++; // increment (postfix) and assign cout << "\nTime1="; Time1.display(); // display incremented value cout << "\nTime2="; Time2.display(); // display assigned value }
ये Program Object को Return करने से पहले उसे Increment करता है लेकिन Object को Return करने के लिए
return TTime(hours, minutes);
Statement के स्थान पर
return *this;
Statement लिखा गया है। इसके प्रयोग के कारण Function से Return होते समय TTime Object की एक और Temporary Copy नहीं बनती है और Object By Reference Return हो जाता है। चूंकि Postfix Operator के सम्बंध में हम ऐसा इसलिए नहीं कर सकते हैं, क्योंकि Object का मान Increment होने से पहले Object को Return करना पडता है।
Overloaded Operators के Return Value सम्बंध में Operator के Function में Arguments को किस प्रकार से Pass किया जाना चाहिए और Return Value को किस प्रकार से प्राप्त करना चाहिए, इसकी जानकारी निम्न Table में दी जा रही है।
ध्यान रखें कि ये Table केवल इसी Chapter के सम्बंध में ही उपयोगी है। आगे हम friend Functions के बारे में पढेंगे, उस समय इस Table को Use नहीं किया जा सकता है।

इस Table में Assignment Operator को छोडकर सभी Binary Operators को एक * चिन्ह से दर्शाया गया है। सैद्धांतिक रूप से ये सभी Member Functions के बजाय friend Functions होने चाहिएं। जब दो Operators Friend होते हैं तब उन्हें किसी Basic Type के Operator के Left या Right दोनों तरफ समान रूप से Use किया जा सकता है।
Operators की Overloading से फायदा ये होता है कि Source Code समझने में काफी सरल हो जाता है। यानी Time3 = Time1(Time2) के स्थान पर Time3 = Time1 + Time2 लिखा जा सकता है, जिससे Source देखने व समझने में काफी सरल हो जाता है। हम किसी भी Operator को किसी भी प्रकार से Use कर सकते हैं।
जैसे * Operator को / Operator की तरह Overload करके Use कर सकते हैं। लेकिन Overloading का Concept “C++” में Coding को सरल बनाने के लिए किया गया है। इसलिए उचित Overloading ही करनी चाहिए ताकि Coding को आसानी से समझा जा सके।
Binary Operator की Overloading करने पर Operator के Left में Operator के Function का नाम होता है जबकि Operator के Right में जो Operand होता है वह उस Operator Function का Argument होता है। जबकि एक Unary Overloaded Operator को Operand के Left या Right किसी भी तरफ Use किया जा सकता है।
जब कोई Operator किसी Object को Modify ना कर रहा हो, तो उस Object को हमेंशा const रखना चाहिए] ताकि Accidentally उस Object का Data Change ना हो जाए। Operator Overloading एक ऐसी सुविधा है जिसका प्रयोग Programmer अपने Coding को सरल बना, रखने के लिए कर सकता है।
यदि वह Operator को Overload करना ना चाहे तो किसी Operator को बिना Overload किए हुए भी वह Member Functions के प्रयोग द्वारा सभी प्रकार के काम कर सकता है जो वह करना चाहता है।
इसका प्रयोग केवल अपने Program की Fine Tuning करने यानी Program को Readable, Easy, Safe व Faster बनाने के लिए ही किया जाता है। यदि इस पूरे अध्याय को आप Use करना ना चाहें, तो भी आपके Program में किसी प्रकार का कोई अन्तर नहीं आ,गा और आप का Program सामान्य तरीके से काम करेगा।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C++ Programming Language in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C++ Programming Language in Hindi | Page: 666 | Format: PDF