विषय पर बढ़ें

अंतिम अद्यतन: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); इसके तुल्य है:

Animal __animal = animal;
वास्तव में कॉपी कंस्ट्रक्टर ही कॉल हुआ, इसलिए आउटपुट आया:
Animal (const Animal &) is called
उसके बाद Dog के कंस्ट्रक्टर के भीतर का आउटपुट प्रिंट होता है।

अंत में डिस्ट्रक्टर कॉल होता है, प्रोग्राम समाप्त।

दूसरा प्रकार: कंस्ट्रक्टर में असाइनमेंट द्वारा ऑब्जेक्ट का आरंभीकरण।

कंस्ट्रक्टर को इस प्रकार बदलें:

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); कॉल होता है, तो वह इसके तुल्य है:

पहले ऑब्जेक्ट परिभाषित होता है, फिर असाइनमेंट होता है; इसलिए पहले डिफ़ॉल्ट कंस्ट्रक्टर, फिर = ऑपरेटर ओवरलोड फंक्शन कॉल होता है।

// 假设之前已经有了animal对象
Animal __animal;
__animal = 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 हटाकर

Dog(int age)  {
    std::cout << "Dog(int age) is called" << std::endl;
}
प्रोग्राम चलाइए:

error: no matching function for call to ‘Animal::Animal()’

चूँकि 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_;
};

निम्नलिखित त्रुटि आती है:

error: uninitialized reference member in ‘int&’

इसे नीचे जैसा बदलना चाहिए:

Animal(int age, std::string name) : age_(age), name_(name) {
    std::cout << "Animal(int age) is called" << std::endl;
}

संबंधित विषय

टिप्पणियाँ