अंतिम अद्यतन:2026-10-12
C++ क्लास इनिशियलाइज़र लिस्ट इडियम¶
- const मेंबर का आरंभीकरण केवल कंस्ट्रक्टर की initializer list में ही किया जा सकता है
- reference मेंबर का आरंभीकरण भी केवल कंस्ट्रक्टर की initializer list में ही किया जा सकता है
- ऑब्जेक्ट मेंबर (जिस ऑब्जेक्ट मेंबर की संगत क्लास में डिफ़ॉल्ट कंस्ट्रक्टर नहीं है) का आरंभीकरण भी केवल कंस्ट्रक्टर की initializer list में ही हो सकता है
क्लासों की नेस्टिंग¶
पहला प्रकार: initializer list का उपयोग।
class Animal {
public:
Animal() {
std::cout << "Animal() is called" << std::endl;
}
Animal(const Animal &) {
std::cout << "Animal (const Animal &) is called" << std::endl;
}
Animal &operator=(const Animal &) {
std::cout << "Animal & operator=(const Animal &) is called" << std::endl;
return *this;
}
~Animal() {
std::cout << "~Animal() is called" << std::endl;
}
};
class Dog {
public:
Dog(const Animal &animal) : __animal(animal) {
std::cout << "Dog(const Animal &animal) is called" << std::endl;
}
~Dog() {
std::cout << "~Dog() is called" << std::endl;
}
private:
Animal __animal;
};
int main() {
Animal animal;
std::cout << std::endl;
Dog d(animal);
std::cout << std::endl;
return 0;
}
रन परिणाम:
Animal() is called
Animal (const Animal &) is called
Dog(const Animal &animal) is called
~Dog() is called
~Animal() is called
~Animal() is called
ऊपर से नीचे क्रमवार विश्लेषण:
main फंक्शन में Animal animal; डिफ़ॉल्ट कंस्ट्रक्टर कॉल करता है।
Dog d(animal); इसके तुल्य है:
अंत में डिस्ट्रक्टर कॉल होता है, प्रोग्राम समाप्त।
दूसरा प्रकार: कंस्ट्रक्टर में असाइनमेंट द्वारा ऑब्जेक्ट का आरंभीकरण।
कंस्ट्रक्टर को इस प्रकार बदलें:
Dog(const Animal &animal) {
__animal = animal;
std::cout << "Dog(const Animal &animal) is called" << std::endl;
}
Animal() is called
Animal() is called
Animal & operator=(const Animal &) is called
Dog(const Animal &animal) is called
~Dog() is called
~Animal() is called
~Animal() is called
जब Dog d(animal); कॉल होता है, तो वह इसके तुल्य है:
पहले ऑब्जेक्ट परिभाषित होता है, फिर असाइनमेंट होता है; इसलिए पहले डिफ़ॉल्ट कंस्ट्रक्टर, फिर = ऑपरेटर ओवरलोड फंक्शन कॉल होता है।
सारांश
उपरोक्त से हम निम्नलिखित निष्कर्ष पर पहुँचते हैं:
- क्लास के भीतर अन्य कस्टम class या struct शामिल हों, तो initializer list अपनाने पर वास्तव में ऑब्जेक्ट बनते ही उसका आरंभीकरण हो जाता है
- जबकि क्लास के भीतर असाइनमेंट का तरीका अपनाने पर, वह पहले ऑब्जेक्ट परिभाषित कर फिर असाइनमेंट करने के तुल्य है — प्रायः पहले डिफ़ॉल्ट कंस्ट्रक्टर, फिर = ऑपरेटर ओवरलोड फंक्शन कॉल होता है।
डिफ़ॉल्ट कंस्ट्रक्टर रहित इनहेरिटेंस संबंध में¶
अब मान लीजिए उपरोक्त संबंध को इनहेरिटेंस में बदल दिया जाए, तथा Animal तथा Dog के कंस्ट्रक्टर बदल दिए जाएँ — नीचे का कोड:
class Animal {
public:
Animal(int age) {
std::cout << "Animal(int age) is called" << std::endl;
}
Animal(const Animal & animal) {
std::cout << "Animal (const Animal &) is called" << std::endl;
}
Animal &operator=(const Animal & amimal) {
std::cout << "Animal & operator=(const Animal &) is called" << std::endl;
return *this;
}
~Animal() {
std::cout << "~Animal() is called" << std::endl;
}
};
class Dog : Animal {
public:
Dog(int age) : Animal(age) {
std::cout << "Dog(int age) is called" << std::endl;
}
~Dog() {
std::cout << "~Dog() is called" << std::endl;
}
};
उपरोक्त में initializer list द्वारा बेस क्लास के पैरामीटर-युक्त कंस्ट्रक्टर को तर्क पास किए गए; यदि initializer list से न पास किया जाए, तो क्या प्रभाव पड़ेगा?
initializer list हटाकर
प्रोग्राम चलाइए:चूँकि Animal में डिफ़ॉल्ट कंस्ट्रक्टर नहीं है, इसलिए त्रुटि आई; ऐसी समस्या आपदा के समान होती है, हमें इससे यथासंभव बचना चाहिए — initializer list द्वारा बेस क्लास के कंस्ट्रक्टर को आरंभीकृत किया जा सकता है।
क्लास में const डेटा मेंबर तथा reference डेटा मेंबर¶
विशेषतः reference डेटा मेंबर का आरंभीकरण अवश्य ही initializer list से होना चाहिए, असाइनमेंट से नहीं!
उदाहरण: उपरोक्त Animal में private मेंबर जोड़कर कंस्ट्रक्टर बदलें:
class Animal {
public:
Animal(int age,std::string name) {
std::cout << "Animal(int age) is called" << std::endl;
}
private:
int &age_;
const std::string name_;
};
निम्नलिखित त्रुटि आती है:
इसे नीचे जैसा बदलना चाहिए:
Animal(int age, std::string name) : age_(age), name_(name) {
std::cout << "Animal(int age) is called" << std::endl;
}
संबंधित विषय¶
- C++ डिफ़ॉल्ट कंस्ट्रक्टर से बचना | C++那些事
- C++ में फ़ंक्शन टेम्पलेट की जगह क्लास टेम्पलेट | C++那些事
- C++ copy-and-swap इडियम | C++那些事
- C++ डिपेंडेंसी इंजेक्शन | C++那些事
- C++ enum class स्ट्रॉन्ग टाइप्ड एनम | C++那些事
- C++ Header-Only तथा कार्यान्वयन का पृथक्करण | C++那些事
- C++ लेज़ी इवैल्यूएशन इडियम | C++那些事
- C++ लुकअप टेबल इडियम | C++那些事
- C++ मेंबर पॉइंटर तथा टाइप जानकारी | C++那些事
- C++ Mixin इडियम | C++那些事