Reputation: 31
#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
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
Reputation: 9735
All derived class from Employee
must to implement all pure virtual methods, otherwise they cannot be instanced.
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.
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