5

I have an assignment which deals with inheritance.

I have a Base Class of Employee(), which Manager(), and Intern() inherit from.

My instructor gave us the following instruction:

In main() declare an array of staff pointers and initialize them to the following records:

Manager("IT", 100, "MF1", "ML1")
Manager("HR", 50, "MF2", "ML2")
Intern("SIUE", 0, "IF1", "IL1")
Intern("SLU", 0, "IF2", "IL2")

Then i have to loop through and display the array. The output he provides as an example shows that the Manager() and Intern() toString() methods must have been called, as specific information related to the child classes was ouput. However, when accessing the array, im getting employee pointers, not pointers to the child. I've attached the screenshot he provided.

Screenshot of what my output needs to look like

I'm not sure how i'm supposed to accomplish this.

Here's my staff array declaration:

Employee * staff = new Employee[4];

I can't store a pointer to the Manager() object i don't think. Unless there is someway i can fan-dangle this:

staff[0] = new Manager("IT", 100, "MF1", "ML1");

It seems my only option is doing something like this(how would i do this in one line btw?):

Employee * e = new Manager("IT", 100, "MF1", "ML1");
staff[0] = *e;

But obviously now when i do this:

cout << staff[0].toString();

I'm going to get the base class Employee() toString() method, not the child class.

Here are my following two classes definitions for Employee() and Manager() in case it's relevant:

class Employee{

private:
    int eid;
    string firstName;
    string lastName;

public:
    Employee();
    Employee(int eid, string fname, string lname);
    void setEID(int eid);
    void setFirstName(string fname);
    void setLastName(string lname);
    int getEID();
    string getFirstName();
    string getLastName();
    virtual string toString();
};


class Manager : public Employee, IPayable{

private:
    string department;

public:
    Manager();
    Manager(string dept, int eid, string fname, string lname);
    double pay();
    void setDepartment(string d);
    string getDepartment();
    string toString();
};

And here is how i assumed i would implement the 2 toString() methods, with the Employee toString() embedded within the Manager() toString():

string Employee::toString(){
    return "{eid = " + std::to_string(getEID()) + ", firstName = " + getFirstName() + ", lastName = " + getLastName() + "}";  
}

string Manager::toString(){
    return "Manager{" + Employee::toString() + ", department = " + getDepartment() + ", salary = " + std::to_string(pay()) +"}";
}
SomeRandomDeveloper
  • 489
  • 2
  • 13
  • 33

5 Answers5

3

What you want is an array of pointers:

Employee *staff[4];

Now you can assign pointers to Employee, and therefore pointers to children of Employee to it:

staff[0] = new Manager("IT", 100, "MF1", "ML1");

And then you can call functions of Employee :

staff[0]->toString();
Cyrille Ka
  • 15,328
  • 5
  • 38
  • 58
  • Is there any way to distinguish if an array entry is a Manager or just an Employee? – C_B Feb 10 '14 at 13:23
  • @CiaranBaselmans: have a look at this question http://stackoverflow.com/questions/500493/c-equivalent-of-instanceof – Cyrille Ka Feb 10 '14 at 15:08
2

Here is one way:

Manager manager1("IT", 100, "MF1", "ML1");
Manager manager2("HR", 50, "MF2", "ML2");
Intern intern1("SIUE", 0, "IF1", "IL1")
Intern intern2("SLU", 0, "IF2", "IL2")

Employee *staff[4] = {
  &manager1,&manager2,&intern1,&intern2
};
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
2
typedef std::unique_ptr<Employee> EmployeePtr;
typedef std::array<EmployeePtr,4> Employees;
Employees employees =
{
    new Manager("IT", 100, "MF1", "ML1"),
    new Manager("HR", 50, "MF2", "ML2"),
    new Intern("SIUE", 0, "IF1", "IL1"),
    new Intern("SLU", 0, "IF2", "IL2")
};

Stored. What else was there? How to access.

employees[0]->toString();

Done.

Öö Tiib
  • 10,809
  • 25
  • 44
1

I can't store a pointer to the Manager object i don't think

Yes, you can. Or at least, you can have a pointer of type Employee* which points to an object of type Manager. After all, Managers are Employees (this is what your inheritance says), so that makes sense.

Since your toString() function is marked as virtual, and Manager overrides its implementation, when invoked on an object of type Manager through a pointer of type Employee*, the specialized implementation of Manager will be picked.

The following, on the other hand, won't compile (you are assigning an object value to a pointer value):

staff[0] = *e;

So don't even try it. Instead, use this:

staff[0] = new Manager(...);
...
staff[0]->toString();

As a final remark, when you use raw pointers, don't forget to delete them before they go out of scope, or you will have memory leaks. In fact, you should consider using smart pointers, which take care of object lifetime automatically.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
1

It seems your class is on inheritance, not arrays, so I will just use vectors..

std::vector<Employee*> staff;

staff.push_back(new Manager);
staff.push_back(new Intern);

You now have an array that is full of Employee pointers. The toString() method of Employee is virtual, so this will call the member methods on each Manager and Intern object you've allocated.

staff[0]->toString(); // Manager toString()
staff[1]->toString(); // Intern toStrin()

Remember to free you memory when you're done!

Aesthete
  • 18,622
  • 6
  • 36
  • 45