मुझे अपने ऑब्जेक्ट्स में "getDegreeProgram ()" विधि तक पहुंचने में परेशानी हो रही है जो मेरे पॉइंटर्स की सरणी पर सेट हैं; मेरे सभी बेसक्लास तरीके काम कर रहे हैं, लेकिन किसी कारण से, मेरे सबक्लास तरीके भी दिखाई नहीं दे रहे हैं। मुझे संदेह है कि मेरे पास सिंटैक्स सही नहीं है, और यह मेरी सभी उप-वर्ग वस्तुओं को छात्र के बेसक्लास में परिवर्तित कर रहा है।

रोस्टर.एच:

   class roster { 
   private:   
   student** classRosterArray; //array of pointers

roster.cpp फ़ंक्शन जो मेरे ऑब्जेक्ट बनाता है और उन्हें पॉइंटर्स की सरणी में सेट करता है


   void roster::createStudentObject() {
      classRosterArray = new student *[5]; //array of pointers
   if (degreeProgramInput == "NETWORK") {
      classRosterArray[rosterCounter] = new networkStudent();
   }
   else if (degreeProgramInput == "SECURITY") {
      classRosterArray[rosterCounter] = new securityStudent();
   }
   else classRosterArray[rosterCounter] = new softwareStudent();  
   }

student.h विचाराधीन उपवर्ग (वे मेरे बेसक्लास "छात्र" के उपवर्ग हैं)

    class networkStudent:public student {
    private: 
      int networkDegree;
    public:
      int getDegreeProgram();
      networkStudent();
    };
    class securityStudent:public student {
    private:
      int securityDegree;
    public:
      int getDegreeProgram();
      securityStudent();
    };
    class softwareStudent:public student {
    private:
      int softwareDegree;
    public:
      int getDegreeProgram();
      softwareStudent();
    };    
0
C. Downer 29 पद 2018, 04:40

2 जवाब

सबसे बढ़िया उत्तर

जहाँ तक मुझे समझ में आया, आप classRosterArray के तत्वों तक पहुँचने का प्रयास कर रहे हैं और getDegreeProgram() को कॉल करने का प्रयास कर रहे हैं।

इस समस्या के लिए, getDegreeProgram() वर्चुअल फ़ंक्शन बनाएं।

student.h

class student {
...

public:
    virtual int getDegreeProgram() = 0; // pure virtual function
};

छात्रों के उपवर्ग

class networkStudent:public student {
private: 
  int networkDegree;
public:
  virtual int getDegreeProgram();
  networkStudent();
};
class securityStudent:public student {
private:
  int securityDegree;
public:
  virtual int getDegreeProgram();
  securityStudent();
};
class softwareStudent:public student {
private:
  int softwareDegree;
public:
  virtual int getDegreeProgram();
  softwareStudent();
};

सुझाव:

इस मामले में, क्योंकि getDegreeProgram() एक गेटर फ़ंक्शन प्रतीत होता है, मुझे लगता है कि आपको इसे एक कॉन्स्ट फ़ंक्शन के रूप में घोषित करना चाहिए।

संपादित करें:

जैसा कि Richard ने ठीक ही कहा है, C++ 11 में, override कीवर्ड को उपवर्गों के लिए इस उद्देश्य के लिए पेश किया गया था। तो, आप virtual int getDegreeProgram(); लिखने के बजाय int getDegreeProgram() override; भी लिख सकते हैं।

1
Kunal Puri 29 पद 2018, 07:46

आप इसके बारे में दो तरीके अपना सकते हैं।

  1. रनटाइम पॉलीमॉर्फिज्म - इस विधि में कम कोड रिफैक्टरिंग की आवश्यकता होगी लेकिन रनटाइम की कीमत पर। एक बहुरूपी वर्ग के प्रत्येक उदाहरण में वर्चुअल फ़ंक्शन के विभिन्न संस्करणों के लिए पॉइंटर्स की एक तालिका (vtable) के लिए एक पॉइंटर (vptr) होगा। इस तालिका का उपयोग रनटाइम पर वर्चुअल फ़ंक्शन के सही संस्करण को खोजने के लिए किया जाएगा।

आप आधार वर्ग यानी Student में getDegreeProgram फंक्शन को वर्चुअल बनाकर यहां रनटाइम पॉलीमॉर्फिज्म हासिल कर सकते हैं और इसे व्युत्पन्न कक्षाओं में ओवरराइड कर सकते हैं। securityStudent, networkStudent और softwareStudent.

class Student {
...
public:
  virtual int getDegreeProgram() = 0; // notice the virtual keyword and 0 at the end. 
                                      // 0 is for saying that it is pure virtual, meaning
                                      // we don't have any definition for this function in
                                      // this class. Such a class is also called as 
                                      // abstract class
...
}

class securityStudent : Student {
...
public:
 int getDegreeProgram() override 
 {
     // do the stuff you want to do
 }
...
}

//  driver stub
...
 Student *student;
 securityStudent sStudent;
 networkStudent nStudent;
 .
 .
 student = &sStudent;
 student->getDegreeProgram(); // calls security student implementation of getDegreeProgram
 student = &nStudent;
 student->getDegreeProgram(); // calls network student implementation of getDegreeProgram
...
  1. स्टेटिक पॉलीमॉर्फिज्म या सीआरटीपी या सिम्युलेटेड डायनेमिक बाइंडिंग - यह विधि ऊपर की तरह ही काम करती है लेकिन कुछ कास्टिंग जादू (नीचे) के माध्यम से संकलन समय पर प्रकार जानने के लाभ के साथ। यहां तक ​​​​कि इस दृष्टिकोण की अपनी सीमाएं हैं जैसे क्लूडी सिंटैक्स और कुछ मात्रा में रिफैक्टरिंग जो पहले मामले की तुलना में बहुत अधिक है और टेम्पलेट्स आदि की संक्षिप्तता के कारण पठनीयता की कमी है।

यहाँ तरकीब यह है कि व्युत्पन्न वर्ग की जानकारी संकलित समय पर प्राप्त की जाए और बेस क्लास के this पॉइंटर को व्युत्पन्न वर्ग के टाइपकास्ट किया जाए। :-)

template <typename StudentType>
class Student {
...
public:
  int getDegreeProgram() 
  {
     return (static_cast<StudentType*>(this))->getDegreeProgramImpl();
  }
...
}

class securityStudent : public Student<securityStudent> {
...
public:
  int getDegreeProgramImpl()
  {
    // write your specifc implementation here
  }
...
}

// driver stub
...
 securityStudent sStudent;
 networkStudent nStudent;
 .
 .
 sStudent.getDegreeProgram(); // calls security student implementation of getDegreeProgram
 nStudent.getDegreeProgram(); // calls network student implementation of getDegreeProgram
...
0
Raghu 29 पद 2018, 15:25