Связанный список, содержащий различные объекты производных классов в C ++ - PullRequest
0 голосов
/ 05 февраля 2020

Как мы можем создать связанный список, который может содержать другой класс объекта. например, если человек является базовым классом, и у него есть ученик и учитель в качестве производного класса, то как я могу создать связанный список, который может содержать оба класса объектов, таких как ученик и учитель. ниже я написал исходный код для этого, но он не работает.

#include<iostream>
#include<string>
using namespace std;

int classNum;

class person
{
    public:
        string name;

    public:
        person(string="");
        void show_p_name();

};

class student:public person
{
    public:
        string s_name;
        int rollnum;

    public:
        student(string="", string="", int=100);
        void show_name();

};

class worker:public person
{
    public:
        string w_name;
        int work_id;

    public:
        worker(string="", string="", int=200);
        void show_name();

};

// person
person::person(string nm)
{
    name = nm;
}

void person::show_p_name()
{
    cout << "In person class name is: " << name << endl;
}

// student inheriate person
student::student(string nm, string snm, int rolln)
        :person(nm)
{

    s_name = snm;
    rollnum = rolln;
}

void student::show_name()
{
    cout << "In student class name is: " << s_name << endl;
}

// worker inheriate person
worker::worker(string nm, string wnm, int wid)
        :person(nm)
{
    w_name = wnm;
    work_id = wid;
}

void worker::show_name()
{
    cout << "In worker class name is: " << w_name << endl;
}

// structure declaration
struct Node
{
    person *p;
    struct Node *next;
};


struct Node* createNode()
{
    struct Node *t;

    t = new struct Node;

    classNum++;

    if(t == NULL)
    {
        cout << "Memory Not Allocated\n";
        //exit(0);
    }
    else
    {
        return t;
    }
}

void initLink(struct Node *n)
{
    n->next = NULL;         //Make next as NULL
}

void initNode(struct Node *temp)
{

    if((classNum % 2) == 0)
    {
        /*
        temp->p = new student;
        static_cast<student*>(temp->p)->name = "person_s_sahil";
        static_cast<student*>(temp->p)->s_name = "student_sahil";
        static_cast<student*>(temp->p)->rollnum = 100;
        temp->p = static_cast<student*>(temp->p);
        */

        temp->p = new student();
        temp->p->name = "person_s_sahil";
        temp->p->s_name = "student_sahil";
        temp->p->rollnum = 100;

    }
    else
    {
        /*
        temp->p = new worker;
        static_cast<worker*>(temp->p)->name = "person_w_sahil";
        static_cast<worker*>(temp->p)->w_name = "worker_sahil";
        static_cast<worker*>(temp->p)->work_id = 100;
        temp->p = static_cast<worker*>(temp->p);
        */

       temp->p = new worker()
       temp->p->name = "person_w_sahil";
       temp->p->w_name = "worker_sahil";
       temp->p->work_id = 100;


    }


}

void attachEnd(struct Node **hptr, struct Node *tn)
{
    struct Node *cn;
    if(*hptr == NULL)  //if list is empty
    {
        *hptr = tn;   //attach new node to head
    }
    else
    {
        cn = *hptr;    //get first node call as currunt node
        while(cn->next != NULL)  //get last node
        {
            cn = cn->next;
        }
        cn->next = tn; //attach new node to next of last node
    }


}


void traverse(struct Node *hptr)
{
    struct Node *temp;
    if(hptr == NULL)
    {
        cout << "List is empty\n";
    }
    else
    {
        temp = hptr;
        while(temp != NULL)
        {
            temp->p->show_name();
            temp = temp -> next;
        }

    }
}

main()
{
    struct Node *head = NULL;

    struct Node *temp;

    temp = createNode();

    initLink(temp);

    initNode(temp);

    attachEnd(&head, temp);

    traverse(head);

    // like that I want to create node and attach to linked list
}



Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Правильный подход заключается в создании связанного списка указателей на объекты типа Person. Затем вы будете заполнять его указателями на экземпляры классов Ученик и Учитель. Вы должны создать его динамически (новое ключевое слово)

И теперь magi c поставляется с использованием ключевого слова virtual для объявления метода в классе Person. Проверьте это в google c ++ polymorphism и C ++ виртуальный метод Если вы в последний раз вызовете виртуальный метод для указателя на объект Person, он вызовет правильный метод из производного класса.

Не не забудьте вызвать delete для каждого элемента в списке в конце использования (программы). И для этого вы должны определить virtual destructor в классе Person

В вашем случае вы должны определить класс Person следующим образом:

class person
{
public:
    string name;
    virtual ~person() {};

public:
    person(string="");
    virtual void show_name();
};

Или другой подход мог бы заключаться в использовании dynamic_cast<>(), но для это вам нужно включить в компиляторе. Это называется RTTI (информация о типе времени выполнения). С помощью Dynami c Cast вы можете безопасно кастовать персонажа ученику или учителю Если Dynami c Cast не может выполнить каст, он вернет nullptr. Таким образом, вы можете проверить это значение.

0 голосов
/ 05 февраля 2020

Немного исправленный код (для целей компиляции):

void initNode(struct Node *temp)
{

  if ((classNum % 2) == 0)
  {
    /*
    temp->p = new student;
    static_cast<student*>(temp->p)->name = "person_s_sahil";
    static_cast<student*>(temp->p)->s_name = "student_sahil";
    static_cast<student*>(temp->p)->rollnum = 100;
    temp->p = static_cast<student*>(temp->p);
    */

    auto s = new student();
    temp->p = s;
    temp->p->name = "person_s_sahil";
    s->s_name = "student_sahil";
    s->rollnum = 100;

  }
  else
  {
    /*
    temp->p = new worker;
    static_cast<worker*>(temp->p)->name = "person_w_sahil";
    static_cast<worker*>(temp->p)->w_name = "worker_sahil";
    static_cast<worker*>(temp->p)->work_id = 100;
    temp->p = static_cast<worker*>(temp->p);
    */

    auto p = new worker();
      temp->p = p;
      temp->p->name = "person_w_sahil";
    p->w_name = "worker_sahil";
    p->work_id = 100;


  }


void traverse(struct Node *hptr)
{
  struct Node *temp;
  if (hptr == NULL)
  {
    cout << "List is empty\n";
  }
  else
  {
    temp = hptr;
    while (temp != NULL)
    {
      temp->p->show_p_name();
      temp = temp->next;
    }

  }
}

Если вы исправите свой код, он будет работать (с первого взгляда).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...