Theory
वह till जो खाली खुली
सोमवार, सुबह 7 बजे। Canteen software शुरू होता है, अपना CanteenTill object बनाता है, और opening balance print करता है:
Balance: -734829156
किसी ने वह type नहीं किया। किसी ने कुछ type ही नहीं किया: cash कभी initialise नहीं हुआ, तो यह जो भी garbage उस memory में पहले से था वही रखता है।
"कोई setup() call करना याद रखेगा" पर भरोसा करना उस दिन fail होता है जब कोई भूल जाता है। आपको वह initialisation चाहिए जो object पैदा होते ही automatically run हो।
Theory
Opening और closing rituals
एक canteen बीच में service के दौरान appear नहीं होता: हर सुबह एक opening ritual होती है (float गिनिए, counters पोंछिए, kettle चालू कीजिए), और हर रात एक closing ritual (cash tally कीजिए, drawer lock कीजिए, lights off)।
एक constructor opening ritual है: यह object बनते ही ख़ुद run होता है। एक destructor closing ritual है: यह object destroy होते ही ख़ुद run होता है। किसी को भी कुछ याद रखने की ज़रूरत नहीं।
Theory
Constructor, formally
एक constructor एक special member function है जो:
- class के नाम जैसा ही नाम रखता है,
- कोई return type नहीं रखता, void भी नहीं,
- object बनते ही automatically run होता है।
तीन kinds जो आपको जाननी चाहिए:
- Default: कोई parameters नहीं, safe starting values सेट करता है।
- Parameterized: arguments लेता है:
Item chai("Chai", 12.5); - Copy: दूसरे object से एक 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, formally
एक destructor एक tilde वाला class name है: ~CanteenTill()।
- कोई arguments नहीं लेता और कुछ return नहीं करता।
- इसलिए यह overload नहीं हो सकता: प्रति class exactly एक।
- object के scope से बाहर जाते ही (या delete होते ही) automatically run होता है।
Order matter करता है: objects बनने के उल्टे order में destroy होते हैं (आख़िर में बना, पहले बंद)। बड़े programs में इसका असली काम: resources release करना, files बंद करना, memory free करना जो object ने acquire की थी।
Think first
Print order का अंदाज़ा लगाइए
ऊपर वाली class इस्तेमाल करते हुए, main() CanteenTill a; CanteenTill b(500); बनाता है और फिर ख़त्म होता है। tap करने से पहले: वे exact चार lines लिखिए जो program क्रम में print करता है।
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: उल्टा order, last in first out)
4. Till closed, final balance 0 (a का destructor)
Construction order a, b; destruction order b, a। वह reversal एक guaranteed exam favourite है, और हाँ, यह फिर stack का ही idea है।
Quiz
एक student class के अंदर लिखता है: int CanteenTill() { cash = 0; return 1; }। Till अभी भी garbage के साथ क्यों खुलती है?
- एक return type वाला function constructor NAHI है, बस एक ordinary member function जिसे कोई नहीं call करता
- काम करने के लिए constructors private होने चाहिए
- Constructor का नाम init() होना चाहिए, CanteenTill नहीं
- return 1 cash = 0 चलने से पहले constructor को crash कर देता है
Show the answer
एक return type वाला function constructor NAHI है, बस एक ordinary member function जिसे कोई नहीं call करता
Rule strict है: एक constructor का बिल्कुल कोई return type नहीं होता। int CanteenTill() लिखना एक normal member function बनाता है जो संयोग से class name share करता है और कभी automatically नहीं चलता, तो cash garbage ही रहता है। Options B और C असली rules उल्टे कर देते हैं (constructors आमतौर पर public होते हैं और class name ही रखने चाहिए); option D एक behaviour describe करता है जो C++ में है ही नहीं।
Watch out
ग़ायब होता default constructor
अगर आप कोई constructor नहीं लिखते, compiler आपको एक empty default gift करता है।
जिस moment आप कोई parameterized constructor define करते हैं, वह gift वापस ले लिया जाता है: अब CanteenTill a; compile होने में fail होता है जब तक आप default constructor भी ख़ुद न लिखें। Exams इसे यूँ पूछते हैं "Item(char n[], double p) जोड़ने के बाद Item i; error क्यों देता है?" अब आप जानते हैं: दोनों define कीजिए, या plain form खो दीजिए।
Theory
Constructors और inheritance
जब एक Student (Person से derived) बनता है, Person का constructor पहले run होता है, फिर Student का: extension बनने से पहले base floor बनती है। Destructors उल्टे order में run होते हैं, child पहले। Opening/closing ritual की picture याद रखिए: यह ordering सवाल वहाँ है जहाँ constructors, inheritance और यहाँ तक कि stack चुपचाप हाथ मिलाते हैं।
Summary
Key takeaways
- Constructor: class जैसा नाम, कोई return type नहीं, creation पर automatically run होता है।
- तीन kinds: default (कोई args नहीं), parameterized (args), copy (दूसरे object से बनता है)।
- Destructor: ~ClassName(), कोई arguments नहीं, प्रति class सिर्फ़ एक, destruction पर automatically run होता है।
- Objects बनने के उल्टे order में destroy होते हैं; base derived से पहले construct होता है।
- एक parameterized constructor define करना compiler का free default हटा देता है।
- Return type वाला एक 'constructor' सिर्फ़ एक ordinary function है: classic trick question।
- Memory hook: opening ritual, closing ritual।