0

I am new to programming and just shifted to C++ from C.

I was learning the concepts of inheritance and tried to make a simple application that takes input from the user and show that data on consol, But I am facing some problems running it. My program seems syntactically correct but it crashes frequently. So I wondered if anyone can teach me what to take into consideration while writing the program to prevent those crashes. here is my sample code

/*
Define a class Hospital having rollno and name as data members and member function to 
get and print data. 
Derive a class Ward from class Hospital having data members: ward number and member function to get and print data. 
Derive another class Room from Hospital having data member bed number and nature of illness and member function to get and print data. 
Derive class Patient from Class Ward and Class Room. 
In main () declare 5 object of Class Patient and get and display all the information.
Use the concept of Virtual Base Class and Hybrid Inheritance.
*/
#include <iostream>
#include <string>
using namespace std;

class Hospital
{
    int rollno;
    string name;

public:
    void get()
    {
        cout << "Enter the roll number : ";
        cin >> rollno;
        fflush(stdin);
        cout << "Enter the name :";
        fflush(stdin);
        getline(cin, name);
        fflush(stdin);
    }
    void print()
    {
        cout << "\nRoll No : " << rollno;
        cout << "\nName : " << name;
    }
};
class Ward : public virtual Hospital
{
    int W_number;

public:
    void get()
    {
        // Hospital :: get();
        cout << "Enter the Ward number : ";
        cin >> W_number;
    }
    void print()
    {
        cout << "\nWard number : " << W_number;
    }
};
class Room : virtual public Hospital
{
    int bedNumber;
    string natureOfIllness;

public:
    void get()
    {
        cout << "Enter the bed number of patient : ";
        cin >> bedNumber;
        fflush(stdin);
        cout << "Enter the nature of illness : ";
        fflush(stdin);
        getline(cin, natureOfIllness);
    }
    void print()
    {
        cout << "\nBed Number : " << bedNumber;
        cout << "\nNature of illness : " << natureOfIllness;
    }
};
class Patient : public Ward, public Room
{
public:
    void get()
    {
        Hospital::get();
        Ward::get();
        Room::get();
    }
    void print()
    {
        cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
        Hospital::print();
        Ward::print();
        Room::print();
        cout << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
    }
};
int main()
{
    Patient p[5];
    for (int i = 0; i < 5; i++)
    {
        cout << "\n\nEnter informtion of patient " << i + 1 << endl;
        p[i].get();
    }
    for (int i = 0; i < 5; i++)
    {
        cout << "Informtion of patient " << i + 1 << endl;
        p[i].print();
    }
    return 0;
}

thank you.

setller
  • 43
  • 7
  • 4
    I am not sure I like all the `fflush(stdin);` – drescherjm Jun 26 '21 at 16:03
  • This is a very strange inheritance structure. Virtual inheritance, multiple inheritance, but no virtual methods? `natureOfIllness` is a member of the `Room` class? – Nathan Pierson Jun 26 '21 at 16:04
  • 6
    `class Ward : public virtual Hospital` -- A `Ward` is a `Hospital`? `class Room : virtual public Hospital` -- A `Room` is a `Hospital`? `class Patient : public Ward, public Room` -- A `Patient` is a `Ward` and a `Room`? I think you may want to focus on your design. – PaulMcKenzie Jun 26 '21 at 16:05
  • The method to prevent your code from crashing is to write good code and to use a debugger to verify your code. Step though the code line by line with a debugger to verify it is doing what you expect. Also check inputs. Don't assume a person will type in valid data. – drescherjm Jun 26 '21 at 16:05
  • 1
    A hospital should contain rooms, wards and patients. A patient should not be a hospital or ward. – drescherjm Jun 26 '21 at 16:06
  • A room should probably contain beds. A patient should have symptoms and possibly illnesses – drescherjm Jun 26 '21 at 16:07
  • 1
    As @drescherjm hinted at `fflush(stdin);` causes undefined behavior. There is no reason to use this. – Lukas-T Jun 26 '21 at 16:09
  • *I am new to programming and just shifted to C++ from C.* -- Looks like you should know about public inheritance. When you use public inheritance, you're supposed to model an "is-a" principle. That's why your inheritance setup doesn't really make much sense. – PaulMcKenzie Jun 26 '21 at 16:13
  • Related to the choice of inheritance versus composition: [https://stackoverflow.com/questions/2218937/has-a-is-a-terminology-in-object-oriented-language](https://stackoverflow.com/questions/2218937/has-a-is-a-terminology-in-object-oriented-language) – drescherjm Jun 26 '21 at 16:14
  • thank you @drescherjm for your valuable add-ons. – setller Jun 26 '21 at 16:19
  • @churill I have used `fflush(stdin)` to clear the input buffer to make sure that it clears the `'\n'` after input of string. – setller Jun 26 '21 at 16:22
  • 1
    @setller For this purpose use [`ignore`](https://en.cppreference.com/w/cpp/io/basic_istream/ignore). Using `fflush` on input streams causes undefined behavior. – Lukas-T Jun 26 '21 at 16:25

2 Answers2

0

When you inherit from a class you need to make the destructor virtual So Hospital should have a virtual destructor.

If you want to override functions declare them virtual in the base class

virtual void get(); virtual void print();

otherwise you are hiding the functions/ Always initialize all member variables

Just write

class Ward : public Hospital {...}

But the fundamental problem with your code is that using Hospital as base class doesn't make sense, a Ward is not a kind of Hospital

You should instead treat the Hospital as a container, so called composition.

The Hospital contains one or more wards so use Hospital as the container, containing a Wards have Rooms, Rooms have Patients,

Now if you want to have the same behavior in all your classes you could create an interface for get/set for instance and use that instead to inherit from.

struct IGetPrint 
{
  virtual void get() = 0;
  virtual void print() = 0;
  ~IGetPrint() = default;
};

class Hospital : public IGetPrint
{
public:
   void get() override
   {
     std::cout << "Enter the roll number : ";
     std::cin >> rollno;
     std::cout << "Enter the name :";
     std::getline(std::cin, name);
   }
   void print() override
   {
     std::cout << "\nRoll No : " << rollno;
     std::cout << "\nName : " << name << std::flush;
   }
protected:
   int rollno{0};
   std::string name;
};


// side note, do not use fflush(stdin) use cin.ignore instead 
// otherwise you will undefined behavior
AndersK
  • 35,813
  • 6
  • 60
  • 86
-3

try using void main() instead of int main and end it with getch() with using #include<stdlib.h> it might help you out sometimes I used to face this type of problem and got sorted by doing that

divya
  • 1
  • 1
  • But why? `void main()` is not even specified as program entry point by the standard. And `getch` is an _ancient_ function that is also not part of the C++ standard. So why do that? – Lukas-T Jun 26 '21 at 18:04