Theory
એ till જે ખાલી ખૂલ્યું
સોમવાર, સવારે 7. Canteen નું software શરૂ થાય છે, પોતાનો CanteenTill object બનાવે છે, અને શરૂઆતની બાકી છાપે છે:
Balance: -734829156
એ કોઈએ ટાઇપ કર્યું નથી. કોઈએ કશું જ ટાઇપ કર્યું નથી: cash ક્યારેય શરૂ કરાયો જ નહોતો, એટલે એમાં એ memory માં પહેલાં જે કચરો પડ્યો હતો એ જ છે.
"કોઈ ને કોઈ setup() બોલાવવાનું યાદ રાખશે" પર આધાર રાખવો એ દિવસે નિષ્ફળ જાય છે જે દિવસે કોઈ ભૂલી જાય. તમને જોઈએ છે એવી શરૂઆત જે object જન્મે એ જ ક્ષણે આપોઆપ ચાલે.
Theory
ખોલવાની અને બંધ કરવાની વિધિ
Canteen ક્યારેય સેવાની વચ્ચે અમસ્તું પ્રગટ થતું નથી: દરેક સવારે ખોલવાની વિધિ હોય છે (છૂટા પૈસા ગણો, counters લૂછો, કીટલી ચાલુ કરો), અને દરેક રાત્રે બંધ કરવાની વિધિ (રોકડ મેળવો, ખાનું તાળું મારો, બત્તી બંધ).
Constructor એ ખોલવાની વિધિ છે: object સર્જાય ત્યારે એ જાતે ચાલે છે. Destructor એ બંધ કરવાની વિધિ છે: object નાશ પામે ત્યારે એ જાતે ચાલે છે. કોઈએ બેમાંથી એકેય યાદ રાખવાનું નથી.
Theory
Constructor, ઔપચારિક રીતે
Constructor એ એવું ખાસ member function છે જે:
- class જેવું જ નામ ધરાવે છે,
- કોઈ return type નથી ધરાવતું, void પણ નહીં,
- object સર્જાય ત્યારે આપોઆપ ચાલે છે.
તમારે જાણવા જ પડે એવા ત્રણ પ્રકાર:
- Default: કોઈ parameters નહીં, સલામત શરૂઆતનાં મૂલ્યો ગોઠવે છે.
- Parameterized: દલીલો લે છે:
Item chai("Chai", 12.5); - Copy: બીજામાંથી object બનાવે છે:
Item second = chai;
Practical
એ till જે પોતાની જાતે ખૂલે છે
#include <iostream>
using namespace std;
class CanteenTill {
private:
double cash;
public:
CanteenTill() { // default constructor
cash = 0;
cout << "Till opened, balance 0" << endl;
}
CanteenTill(double openingFloat) { // parameterized constructor
cash = openingFloat;
cout << "Till opened with float " << cash << endl;
}
~CanteenTill() { // destructor: note the tilde
cout << "Till closed, final balance " << cash << endl;
}
};
int main() {
CanteenTill a; // prints: Till opened, balance 0
CanteenTill b(500.0); // prints: Till opened with float 500
return 0;
} // going out of scope: b closes first, then a
Theory
Destructor, ઔપચારિક રીતે
Destructor એ class નું નામ છે આગળ tilde સાથે: ~CanteenTill().
- કોઈ દલીલ લેતું નથી અને કશું પાછું આપતું નથી.
- એટલે એને overload કરી શકાતું નથી: class દીઠ બરાબર એક જ.
- Object scope ની બહાર જાય (કે delete થાય) ત્યારે આપોઆપ ચાલે છે.
ક્રમ મહત્ત્વનો છે: objects સર્જનના ઊલટા ક્રમમાં નાશ પામે છે (છેલ્લે બન્યો એ પહેલો બંધ). મોટા programs માં એનું ખરું કામ: સાધનો છોડવાં, files બંધ કરવી, object એ મેળવેલી memory મુક્ત કરવી.
Think first
છપાવાનો ક્રમ ધારો
ઉપરનો class વાપરીને, main() એ CanteenTill a; CanteenTill b(500); બનાવે છે અને પછી પૂરું થાય છે. Tap કરતાં પહેલાં: program જે ચાર લીટીઓ છાપશે એ ક્રમમાં લખો.
Show the answer
1. Till opened, balance 0 (a નું default constructor)
2. Till opened with float 500 (b નું parameterized constructor)
3. Till closed, final balance 500 (b નું destructor: ઊલટો ક્રમ, છેલ્લે અંદર પહેલો બહાર)
4. Till closed, final balance 0 (a નું destructor)
સર્જનનો ક્રમ a, b; નાશનો ક્રમ b, a. એ ઊલટાવવું પરીક્ષાનું ખાતરીબદ્ધ પ્રિય છે, અને હા, એ ફરી stack નો જ વિચાર છે.
Quiz
એક student class ની અંદર લખે છે: int CanteenTill() { cash = 0; return 1; } તો till હજી કચરા સાથે કેમ ખૂલે છે?
- Return type વાળું function એ constructor **નથી**, ફક્ત એક સામાન્ય member function છે જેને કોઈ બોલાવતું નથી
- Constructors ને કામ કરવા માટે private હોવું જ પડે
- Constructor નું નામ init() હોવું જોઈએ, CanteenTill નહીં
- cash = 0 ચાલે એ પહેલાં return 1 constructor ને તોડી નાખે છે
Show the answer
Return type વાળું function એ constructor **નથી**, ફક્ત એક સામાન્ય member function છે જેને કોઈ બોલાવતું નથી
નિયમ કડક છે: constructor ને કોઈ પણ return type હોતું જ નથી. int CanteenTill() લખવાથી એક સામાન્ય member function બને છે જેનું નામ સંજોગવશાત્ class જેવું છે અને જે ક્યારેય આપોઆપ ચાલતું નથી, એટલે cash કચરો જ રહે છે. વિકલ્પ B અને C ખરેખરા નિયમો ઊલટાવે છે (constructors સામાન્ય રીતે public હોય છે અને એમનું નામ class જેવું હોવું જ પડે); વિકલ્પ D એવું વર્તન વર્ણવે છે જે C++ માં છે જ નહીં.
Watch out
અદૃશ્ય થતું default constructor
જો તમે કોઈ constructor ન લખો, તો compiler તમને એક ખાલી default ભેટ આપે છે.
તમે જે ક્ષણે કોઈ પણ parameterized constructor વ્યાખ્યાયિત કરો, એ ભેટ પાછી ખેંચાઈ જાય છે: હવે CanteenTill a; compile થતું નથી, સિવાય કે તમે default constructor પણ જાતે લખો. પરીક્ષાઓ એને આમ પૂછે છે: "Item(char n[], double p) ઉમેર્યા પછી Item i; ભૂલ કેમ આપે છે?" હવે તમને ખબર છે: બંને લખો, નહીં તો સાદું સ્વરૂપ ગુમાવો.
Theory
Constructors inheritance ને મળે છે
જ્યારે Student (જે Person માંથી ઊતરેલો છે) સર્જાય છે, ત્યારે Person નું constructor પહેલાં ચાલે છે, પછી Student નું: વિસ્તાર બાંધતાં પહેલાં નીચેનો માળ બંધાય છે. Destructors ઊલટા ક્રમમાં ચાલે છે, સંતાન પહેલું. ખોલવાની અને બંધ કરવાની વિધિનું ચિત્ર માથામાં રાખો: ક્રમનો આ પ્રશ્ન એ જગ્યા છે જ્યાં constructors, inheritance અને stack સુધ્ધાં ચૂપચાપ હાથ મિલાવે છે.
Summary
Key takeaways
- Constructor: class જેવું જ નામ, કોઈ return type નહીં, સર્જન વખતે આપોઆપ ચાલે છે.
- ત્રણ પ્રકાર: default (દલીલ વગર), parameterized (દલીલો સાથે), copy (બીજા object માંથી બનાવે).
- Destructor: ~ClassName(), કોઈ દલીલ નહીં, class દીઠ ફક્ત એક, નાશ વખતે આપોઆપ ચાલે છે.
- Objects સર્જનના ઊલટા ક્રમમાં નાશ પામે છે; base એ derived પહેલાં બંધાય છે.
- Parameterized constructor વ્યાખ્યાયિત કરવાથી compiler નું મફતનું default જતું રહે છે.
- Return type વાળું 'constructor' એ ફક્ત સામાન્ય function છે: જાણીતો છળપ્રશ્ન.
- Memory hook: ખોલવાની વિધિ, બંધ કરવાની વિધિ.