Sunday, November 20, 2011

C++ Tutorial: Some Lab Assignments on Virtual Functions

Question: Write a program to create a class shape with functions to find area of the shapes and display the name of the shape and other essential component of the class. Create derived classes circle, rectangle and trapezoid each having overridden functions area and display. Write a suitable program to illustrate virtual functions and virtual destructor.
Solution:
#include<iostream>
#include<cmath>

using namespace std;

class shape
{
 protected:
  float length, breadth, ar;
 public:
  shape():length(0), breadth(0){}
  shape(float len, float br):length(len), breadth(br) {}
  virtual void area()
  {
   ar =  length * breadth;
  }
  virtual void display()
  {
   cout<<"The required area is: "<<ar ;
  }
  virtual ~shape()
  {
      cout<<"\nDestructor from Base class shape";
  }
};

class rectangle : public shape
{
 public:
  rectangle(){}
  rectangle(float len, float br):shape(len, br){};  /***explicit call to base class constructor***/
  void area()
  {

   ar = length * breadth;
  }
  void display()
  {
   cout<<"\n The area of rectangle is: "<<ar;
  }
  ~rectangle()
  {
            cout<<"\n Destructor from Derived class rectangle";
  }

};

class circle : public shape
{
 private:
  float radius;
 public:
  circle():radius(0.0){}
  circle( float rad):radius(rad){}
  void area()
  {
   ar = 3.1436 * radius * radius;
  }
  void display()
  {
   cout<<"\nThe area of circle is: "<<ar;
  }
  ~circle()
  {

      cout<<"\n Donstructor from derived class Circle ";
  }
};

class trapazoid : public shape
{
 private:
  float l1, l2, h;
 public:
        trapazoid():l1(0),l2(0),h(0){}
  trapazoid(float l11 = 0.0, float l22 = 0.0, float h1 = 0.0):l1(l11), l2(l22), h(h1){}
  void area()
  {
   ar = ((1/2.0)*(l1+l2))*h;
  }
  void display()
  {
   cout<<"\nThe area of Trapazoid is: "<<ar;
  }
        ~trapazoid()
        {

            cout<<"\n Donstructor from derived class trapazoid";
        }
};

int main()
{
// shape *shp
//
circle cr( 2.1);
rectangle rt(2.2, 4.6);
trapazoid tp( 3.6, 4.5, 2.1);
//
// shp = &cr;
// shp->area();
// shp->display();
//
// shp = &rt;
// shp->area();
// shp->display();
//
// shp = &tp;
// shp->area();
// shp->display();

shape *shp[] = {&cr,&rt,&tp};
for(int i=0;i<3;i++){
shp[i]->area();
shp[i]->display();
}
delete shp;
 return 0;
}


Question: Create a class Person and two derived classes Employee, and Student, inherited from class Person. Now create a class Manager which is derived from two base classes Employee and Student. Show the use of the virtual base class.

Solution:
#include<iostream>

using namespace std;

class Person
{
    private:
        char name[20];
    public:
        void get_per_data()
        {
            cout<<"\nEnter the name: ";
            cin>>name;
        }
        void show_per_data()
        {
            cout<<"\nThe name is: "<<name;
        }
};

class Employee :virtual public Person

/***********************************************************************
The   keyword   'virtual'   makes  only   one   copy  of  ger_per_data()
and   show_per_data()   Which   avoids ambiguity.  If we do not   supply
keyword 'virtual' the compiler cannot decides which class' get_per_data()
and show_per_data() to be called    because they are the member funcions
of classes Employee , Student, and Manager as well.
************************************************************************/


{
    private:
        char emp_id[10];
    public:
        void get_data()
        {
            cout<<"Enter Employee ID: ";
            cin>>emp_id;

        }
        void show_data()
        {
            cout<<"\nEmplyee ID: "<<emp_id;
        }
};

class Student : virtual public Person
{
    private:
        char roll_no[10];
    public:
        void get_data()
        {
            cout<<"Enter Roll No: ";
            cin>>roll_no;
        }
        void show_data()
        {
            cout<<"\nRoll No: "<<roll_no;
        }
};

class Manager: public Employee, public Student
{
    private:
        unsigned int salary;
    public:
        void get_data()
        {
            Employee::get_data(); /**calls the get_data() of Employee**/
            Student::get_data();
            cout<<"Enter Salary: ";
            cin>>salary;
        }
        void show_data()
        {
            Employee::show_data();
            Student::show_data();
            cout<<"\nSalary: "<<salary;
        }
};

int main()
{
    Manager m;
    cout<<"Enter data for manager: ";
    m.get_per_data(); /**calls single copy of get_per_data()**/
    m.get_data();
    cout<<"\nThe data on manager is:  ";
    m.show_per_data();
    m.show_data();
    return 0;
}


Question: Write a program with Student as abstract class and create derive classes Engineering, Medicine and Science from base class Student. Create the objects of the derived classes and process them and access them using array of pointer of type base class Student.

Solution:
#include<iostream>

using namespace std;

class Student
{
    protected:
        char name[20], depart[20];
    public:
    /********************************************************************
    The assignment of function with 0 indicates the pure virtual
    function. It doesnot allow the creation of object of class Student
    but pointer to Student can be created. The Student is now Abstract
    class. To make a derive class concrete the member functions of Student
    should be overridden in derived classes. The base class is made abstract
    because it is most generic class so that we donot need its object.
    **********************************************************************/

        virtual void get_data() = 0;
        virtual void show_data() = 0;

};

class Engineering : public Student
{
    public:
        void get_data()
        {
            cout<<"Enter the information of Engineering student ";
            cout<<"\nEnter the name of Student: ";
            cin>>name;
            cout<<"Enter Department: ";
            cin>>depart;
        }
        void show_data()
        {
            cout<<"The Information of Engineering student is ";
            cout<<"\nName : "<<name;
            cout<<"\nDepartment: "<<depart;
        }
};

class Medicine : public Student
{
    public:
        void get_data()
        {
            cout<<"Enter the information of Medicine student ";
            cout<<"\nEnter Name: ";
            cin>>name;
            cout<<"Enter Department: ";
            cin>>depart;
        }
        void show_data()
        {
            cout<<"\nThe information of Medicine student is ";
            cout<<"\nName: "<<name;
            cout<<"\n Department: "<<depart;
        }
};

class Science : public Student
{
    public:
        void get_data()
        {
            cout<<"\nEnter information of Science Student: ";
            cout<<"Enter name: ";
            cin>>name;
            cout<<"Enter Department: ";
            cin>>depart;
        }
        void show_data()
        {
            cout<<"The informaion of Science student is ";
            cout<<"\nName: "<<name;
            cout<<"\nDepartment: "<<depart;
        }
};

int main()
{
    Student *stu[3];
    stu[0] = new Engineering;
    stu[1] = new Medicine;
    stu[2] = new Science;

    for(int i = 0; i<3; i++)
    {
        stu[i]->get_data();
    }
    for(int i = 0; i< 3; i++)
    {
        stu[i]->show_data();
    }
    return 0;
}


Question: Create a polymorphic class Vehicle and create other derived classes Bus, Car and Bike from Vehicle.With this program illustrate RTTI by the use of  dynamic_cast and typeid operators.

Solution:
#include<iostream>
#include<typeinfo>

using namespace std;

class Vehicle
{
    public:
        virtual void show()
        {

        }
};

class Bus: public Vehicle
{

};

class Car: public Vehicle{};

class Bike: public Vehicle{};

int main()
{
    Vehicle *pveh, veh;
    Bus *pbs, bs;
    Car *pcr, cr;
    Bike *pbk, bk;

    pveh = &bs;
    pbs = dynamic_cast<Bus *>(pveh);
    if(pbs)
        cout<<"The Cast to derived pointer pbs is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pbs is Failed"<<endl;

    /******************************************************************************
    Here the cast from base class Vehicle pointer pveh to derived class Bus pointer
    pbs works well bcoz pveh is poining to derived class Bus' Object.
    *******************************************************************************/



    pveh = &cr;
    pcr = dynamic_cast<Car *>(pveh);
    if(pcr)
        cout<<"The Cast to derived pointer pcr is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pcr is Failed"<<endl;


    pveh = &bk;
    pbk = dynamic_cast<Bike *>(pveh);
    if(pbk)
        cout<<"The Cast to derived pointer pbk is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pbk is Failed"<<endl;

    pveh = &veh;
    pbs = dynamic_cast<Bus *>(pveh);
    if(pbs)
        cout<<"The Cast to derived pointer pbs is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pbs is Failed"<<endl;

    /******************************************************************************
    Here the cast from base class Vehicle pointer pveh to derived class Bus pointer
    pbs works well bcoz pveh is poining to base class Vechile's Object.
    *******************************************************************************/


    pveh = &veh;
    pcr = dynamic_cast<Car *>(pveh);
    if(pbs)
        cout<<"The Cast to derived pointer pcr is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pcr is Failed"<<endl;

    pveh = &veh;
    pbk = dynamic_cast<Bike *>(pveh);
    if(pbs)
        cout<<"The Cast to derived pointer pbk is Sucessful"<<endl;
    else
        cout<<"The Cast to derived pointer pbk is Failed"<<endl;



    cout<<"\nThe type id of veh is: "<<typeid(veh).name()<<endl;
    cout<<"The type id of bs is: "<<typeid(bs).name()<<endl;
    cout<<"The type id of cr is: "<<typeid(cr).name()<<endl;

    pveh = &bs;
    cout<<"\nIn pveh = &bs, the type id of pveh is: "<<typeid(*pveh).name()<<endl;

    /**********************************************************************************
    The address of bs is assigned to pveh at runtime. So until runtime, the comiler see
    pveh as a type Vechile. But at runtime the address of bs is assigned to pveh and
    pveh becomes type of bs.
    ***********************************************************************************/


    pveh = &cr;
    cout<<"In pveh = &cr, the type id of pveh is: "<<typeid(*pveh).name()<<endl;

    pveh = &bk;
    cout<<"In pveh = &bk, the type id of pveh is: "<<typeid(*pveh).name()<<endl;

    return 0;

}

No comments:

Post a Comment