Arka Bhowmick
Arka Bhowmick

Reputation: 31

Dynamic Polymorphism Error in code C++

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


class Employee
{
public :
    virtual int calculateSalary()= 0;
    virtual string getName()=0;      
    virtual string getEngineer()=0;            //error
    virtual string getManager()=0;            /error
    virtual string getDirector()=0;              /error

};

class Engineer: public Employee
{
protected:
    string name;
    int salary;
public:
    Engineer(string n,int s):name(n),salary(s){ cout<<endl<<"Engineer    Created"; }
    ~Engineer(){cout<<endl<<"engineer destroyed";}
    int calculateSalary()
    {
        return salary * 2;
    }
    string getName()
    {
        return name;
    }
    string getEngineer()
    {
        return "Engineer";
    }
};

class Manager:public Engineer
{
public:
    Manager(string n,int s): Engineer(n,s) { cout<<endl<<"Manager Created"; }
    ~Manager(){cout<<endl<<"MANAGER destroyed";}
    int calculateSalary()
    {
        return salary * 3;
    }
    string getName()
    {
        return name;
    }
    string getManager()
    {
        return "manager";
    }
};

class Director:public Manager
{
public:
    Director(string n,int s): Manager(n,s) { cout<<endl<<"Director Created"; }
    ~Director(){cout<<endl<<"Director destroyed";}
    int calculateSalary()
    {
        return salary * 4;
    }
    string getName()
    {
        return name;
    }
    string getDirector()
    {
        return "director";
    }
};

int main()
{
    Engineer e1("rohit",20000),e2("soham",21000);
    Manager m1("shyam",23000),m2("ram",23500);
    Director d1("rahul",25000);

    Employee *staff[] = {&e1,&e2,&m1,&m2,&d1};

    for(int i=0;i<5;i++)
    {
        cout<<endl<<"Name : "<<staff[i]->getName() << "\t" << "Salary : " << staff[i]->calculateSalary();
     }

    cout<<endl<<staff[0]->getEngineer();                //error
    cout<<endl<<staff[1]->getEngineer();                //error
    cout<<endl<<staff[2]->getManager();                //error
    cout<<endl<<staff[3]->getManager();                //error
    cout<<endl<<staff[4]->getDirector();                //error

    return 0;
}

/The lines with error are showing errors if i compile this code. i want to know if it is possible to access the getEngineer(),getManager(),getDirector() via the staff pointer. If yes, then how? If not, then why? and is there any alternative to access those functions keeping the data type of staff as it is(i.e Employee) ?/

Upvotes: 3

Views: 66

Answers (2)

HazemGomaa
HazemGomaa

Reputation: 1630

it is possible to access the getEngineer(),getManager(),getDirector() via the staff pointer. If yes, then how?

Yes, you can. However, as @Biagio Festa said you can't have pure virtual functions in your base class Employee without implementing them in your derived ones. So one solution could be having default implementations for those functions in your base class

class Employee
{
 public :
  virtual int calculateSalary()= 0;
  virtual string getName()=0;      
  virtual string getEngineer() { return std::string(); }            
  virtual string getManager() { return std::string(); }
  virtual string getDirector() { return std::string(); }            
};

Then, you can override those functions in your derived classes only when needed like you did in your example.

Upvotes: 1

BiagioF
BiagioF

Reputation: 9735

All derived class from Employee must to implement all pure virtual methods, otherwise they cannot be instanced.

Why does this happen?

A derivative class inherits all methods (and member variables) from the base class.

In you case, base class has some pure virtual methods, and so the sub-classes (Engineer, Manager and Director) as well. A no-abstract class cannot have a pure virtual method, so in order to instantiate those classes, each of them should implement getEngineer() getManager() getDirector() methods.

What is the solution?

The problem in your case is a bad design decision. The base class should represent a uniform interface for all derivative classes.

That's why, the base class Employee should not have method like getEngineer() which is a more specific information.

IMO, a better design decision (just looking at your code) could be:

class Employee {
 public :
  virtual int calculateSalary() = 0;
  virtual string getName() = 0;      
  virtual string getTypeWork() = 0;
};

In that way (exploiting polymorphism property) each derivative class can correctly return a string representing its role job.

Upvotes: 3

Related Questions