Reputation: 1598
I might be going about this wrong way. I'm being asked to create an array of objects of a particular class. That class, however, has two derived classes.
class Employee {
// Some stuff here about the backbone of the Employee class
}
class Salary: public Employee {
// Manipulation for Salary employee
}
class Hourly: public Employee {
// Manipulation for hourly Employee
}
// Main Program
int main (int argc, char**argv) {
Employee data[100]; // Creates an array of Employee objects
while (employeecount > 100 || employeecount < 1) {
cout << "How many employees? ";
cin >> employeecount;
}
for(int x = 0; x <= employeecount; x++) {
while (status != "S" || status != "s"|| status != "H" || status != "h") {
cout << "Employee Wage Class (enter H for hourly or S for Salary)";
cin >> status;
}
if (status == "S" || status == "s") { // Salaried Employee
new
} else { // We valid for hourly or salary, so if its not Salaried it's an hourly
}
}
return 0;
}
The question I want to ask is, can the base class call on the derived class methods? For example, if I created a method for the Salary class named getgross
: Can I invoke a method like this: Employee.getgross()
? If not how can I invoke a subclass method?
Upvotes: 1
Views: 154
Reputation: 327
As everybody else stated, you must use pointers to Employee objects instead of Employee objects in your array. That way any derived class from Employee can be pointed to by the Employee pointers.
I think what you are trying to do is implement the method in the Employee base class and have it be usable by all derived classes. If so, the following should be your answer.
(Borrowed this answer from here):
How can a member function in my derived class call the same function from its base class?
"Use Base::f();
Let’s start with a simple case. When you call a non-virtual function, the compiler obviously doesn’t use the virtual-function mechanism. Instead it calls the function by name, using the fully qualified name of the member function. For instance, the following C++ code…
void mycode(Fred* p)
{
p->goBowling(); // Pretend, Fred::goBowling() is non-virtual
}
…might get compiled into something like this C-like code (the p parameter becomes the this object within the member function):
void mycode(Fred* p)
{
__Fred__goBowling(p); // Pseudo-code only; not real
}
The actual name-mangling scheme is more involved than the simple one implied above, but you get the idea. The point is that there is nothing strange about this particular case — it resolves to a normal function more-or-less like printf().
Now for the case being addressed in the question above: When you call a virtual function using its fully-qualified name (the class-name followed by “::”), the compiler does not use the virtual call mechanism, but instead uses the same mechanism as if you called a non-virtual function. Said another way, it calls the function by name rather than by slot-number. So if you want code within derived class Der to call Base::f(), that is, the version of f() defined in its base class Base, you should write:
void Der::f()
{
Base::f(); // Or, if you prefer, this->Base::f();
}
The complier will turn that into something vaguely like the following (again using an overly simplistic name-mangling scheme):
void __Der__f(Der* this) //Pseudo-code only; not real
{
__Base__f(this); // Pseudo-code only; not real
}
"
Upvotes: 2
Reputation: 12037
Declare getgross()
as virtual
in the Employee
class.
Example:
class Employee {
virtual int getgross();
}
class Salary: public Employee {
virtual int getgross();
}
Whenever you call getgross()
on an Employee*
which points to a Salary
object, getgross()
of Salary
is called.
I added virtual
to Salary::getgross()
too, this would not be needed at the moment, but it's better to include it now, because you could want to derive a class form Salary
later.
The array needs to be an array of pointers to avoid the slicing problem. Even better would be using a vector
of smart pointers.
Upvotes: 2
Reputation: 232
A few thoughts:
Upvotes: 1
Reputation:
The best way to do it, is to make the method getGross() in the base class(virtual method), so that the derived class can take it by inheritance.
Upvotes: 2
Reputation: 36082
To avoid slicing you need to store pointers to the objects
Employee* data[100];
Then you can create the objects from the various derived classes and place them into the array e.g.
data[0] = new Salary;
In order for the right method to be called you need to declare a method in the base class that is virtual then override that in your derived classes.
Upvotes: 3