c++ pure कन्स्ट्रक्टर से सी++ वर्चुअल फ़ंक्शन




virtual function in c++ in hindi (6)

इस प्रश्न का उत्तर यहां दिया गया है:

निम्न उदाहरण क्यों "0" प्रिंट करता है और मुझे उम्मीद है कि "1" प्रिंट करने के लिए इसके लिए क्या परिवर्तन करना चाहिए?

#include <iostream>
struct base {
   virtual const int value() const {
      return 0;
   }
   base() {
      std::cout << value() << std::endl;
   }
   virtual ~base() {}
};

struct derived : public base {
   virtual const int value() const {
      return 1;
   }
};

int main(void) {
   derived example;
}

दरअसल, इस व्यवहार को पाने का एक तरीका है। "सॉफ्टवेयर में हर समस्या को संकेत के स्तर के साथ हल किया जा सकता है।"

/* Disclaimer: I haven't done C++ in many months now, there might be a few syntax errors here and there. */
class parent
{
public:
     parent( ) { /* nothing interesting here. */ };
protected:
     struct parent_virtual
     {
         virtual void do_something( ) { cout << "in parent."; }
     };

     parent( const parent_virtual& obj )
     {
          obj.do_something( );
     }
};

class child : public parent
{
protected:
     struct child_virtual : public parent_virtual
     {
         void do_something( ) { cout << "in child."; }
     };
public:
      child( ) : parent( child_virtual( ) ) { }
};

क्योंकि base पहले बनाया गया है और अभी तक derived में "परिपक्व" नहीं derived है। यह किसी ऑब्जेक्ट पर विधियों को कॉल नहीं कर सकता है जब यह गारंटी नहीं दे सकता कि ऑब्जेक्ट पहले ही ठीक से प्रारंभ हो चुका है।


जब व्युत्पन्न वस्तु का निर्माण किया जा रहा है, तो व्युत्पन्न वर्ग निर्माता के शरीर को बेस क्लास कन्स्ट्रक्टर को पूरा करना होगा। व्युत्पन्न वर्ग कन्स्ट्रक्टर को निर्माणाधीन वस्तु का गतिशील प्रकार कहा जाता है, इससे पहले बेस क्लास इंस्टेंस होता है और व्युत्पन्न क्लास इंस्टेंस नहीं होता है। इस कारण से, जब आप किसी कन्स्ट्रक्टर से वर्चुअल फ़ंक्शन को कॉल करते हैं, तो केवल बेस क्लास वर्चुअल फ़ंक्शन ओवरराइड को कॉल किया जा सकता है।


आपको कन्स्ट्रक्टर से आभासी तरीकों को polymorphically कॉल नहीं करना चाहिए। इसके बजाय आप ऑब्जेक्ट के निर्माण के बाद उन्हें कॉल कर सकते हैं।

आपका कोड निम्नानुसार लिखा जा सकता है

struct base {
   virtual const int value() const {
      return 0;
   }
   base() {
      /* std::cout << value() << std::endl; */
   }
   virtual ~base() {}
};

struct derived : public base {
   virtual const int value() const {
      return 1;
   }
};

int main(void) {
   derived example;
   std::cout << example.value() << std::endl;
}

सी ++ में, आप एक कन्स्ट्रक्टर से वर्चुअल / ओवर्रिडेन विधि को कॉल नहीं कर सकते हैं।

अब, एक अच्छा कारण है कि आप यह कर सकते हैं। "सॉफ़्टवेयर में सर्वोत्तम अभ्यास" के रूप में, आपको अपने कन्स्ट्रक्टर से अतिरिक्त तरीकों को कॉल करने से बचाना चाहिए, यहां तक ​​कि गैर वर्चुअल भी संभव है।

लेकिन, नियम के लिए हमेशा अपवाद होता है, इसलिए आप उन्हें अनुकरण करने के लिए "छद्म कन्स्ट्रक्टर विधि" का उपयोग करना चाह सकते हैं:

#include <iostream>

class base {
   // <constructor>
   base() {
      // do nothing in purpouse
   }
   // </constructor>

   // <destructor>
   ~base() {
      // do nothing in purpouse
   }
   // </destructor>

   // <fake-constructor>
   public virtual void create() {
      // move code from static constructor to fake constructor
      std::cout << value() << std::endl;
   }
   // </fake-constructor>

   // <fake-destructor>
   public virtual void destroy() {
      // move code from static destructor to fake destructor
      // ...
   }
   // </fake-destructor>

   public virtual const int value() const {
      return 0;
   }

   public virtual void DoSomething() {
      // std:cout << "Hello World";
   }
};

class derived : public base {
   // <fake-constructor>
   public override void create() {
      // move code from static constructor to fake constructor
      std::cout << "Im pretending to be a virtual constructor," << std::endl;
      std::cout << "and can call virtual methods" << std::endl;
   }
   // </fake-constructor>


   // <fake-destructor>
   public override void destroy() {
      // move code from static destructor to fake destructor
      std::cout << "Im pretending to be a virtual destructor," << std::endl;
      std::cout << "and can call virtual methods" << std::endl;
   }
   // </fake-destructor>

   public virtual const int value() const {
      return 1;
   }
};

int main(void) {
   // call fake virtual constructor in same line, after real constructor
   derived* example = new example(); example->create();

   // do several stuff with your objects
   example->doSomething();

   // call fake virtual destructor in same line, before real destructor
   example->destroy(); delete example();
}

एक प्लस के रूप में, मैं प्रोग्रामर को केवल फ़ील्ड संरचनाओं के लिए "संरचना" का उपयोग करने और फ़ील्ड, विधियों, रचनाकारों के साथ संरचनाओं के लिए "कक्षा" का उपयोग करने की सलाह देता हूं ...


सामान्य नियम यह है कि आप एक कन्स्ट्रक्टर से वर्चुअल फ़ंक्शन नहीं कॉल करते हैं।







virtual