I've looked around and it turns out there isn't a C++ version of the java instanceof operator. I've also found out that using instanceof is supposed to be bad, for some reason.

So let me tell you why I want to use this instanceof operator so badly. I've got a Vector that holds two types of objects, either Manager or Casual classes, that are both derived from the base class StaffMember.

I want to display the Salary for Manager objects, and the hourlyWage and hoursWorked for the Casual object. First I have to determine whether the item in the Vector is a Manager or a Casual object. So I went looking for an instanceof operator, but no such thing exists. Then I was pointed towards the typeid() function.

I tried it out and my objects are declared as the base class StaffMember. So I think that as I am adding them to this Vector, they are being cast as StaffMembers.

So right now I'm thinking about making two seperate vectors, one for Managers and another for Casual objects. However, it just isn't in the spirit of the assessment. I'll show you some code segments and provide a link to the full project for anyone interested.

From Company.cpp

void Company::addStaff(StaffMember* x)
{
staffList.push_back(x);
numStaff++;
}

void Company::addStaff(Casual* x)
{
staffList.push_back(x);
numStaff++;
}
void Company::addStaff(Manager* x)
{
staffList.push_back(x);
numStaff++;
}

From Company.h

class Company
{
private:
string name;
vector<StaffMember*> staffList;
int numStaff;
public:
//Constructors
Company(string name);
Company();
//Writers
void setName(string name);
//Readers
string getName();
StaffMember* getStaff(int ID);
//Mutators
void addStaff(StaffMember* x);
void addStaff(Manager* x);
void addStaff(Casual* x);
};

From payroll.cpp (The client)

void addFour(Company* westaff)
{
westaff->addStaff(new Manager("Bill Gates", 200000));
westaff->addStaff(new Casual("Angus Cheng", 36, 19.8));
westaff->addStaff(new Manager("Fernando Alonso", 49888));
westaff->addStaff(new Manager("Nelson Piquet", 8000));
}

[Full listing](http:// rapidshare.com/files/215333186/payRoll.rar.html)

Recommended Answers

All 9 Replies

Since you are storing pointer to type objects why not try using polymorhism by writing a base method called displayPay() declared with the keyword virtual that would be overloaded with in each of the inherited classes. Then you can loop through the vector of pointer to StaffMembers calling the displayPay() method and the correct version of displayPay() will be called for each referenced object.

commented: Perfectamundo!!! +12

Here Here!

Since you are storing pointer to type objects why not try using polymorhism by writing a base method called displayPay() declared with the keyword virtual that would be overloaded with in each of the inherited classes. Then you can loop through the vector of pointer to StaffMembers calling the displayPay() method and the correct version of displayPay() will be called for each referenced object.

I have actually done that, although instead of displayPay() I used wage(). One of the requirements is to output the ID, Name, Type e.g. Casual or Manager and Wage of each staff member.

So somehow I must figure out the type of the object.

Nah, in the overridden virtual wage() method, simply put something like cout << "Manager" in the Manager's method, and cout << "Casual" in the Casual's method.

Or make a virtual overridden method for each class that is like "GetType()", and have wage() call GetType(). The proper way to do what you want to do, is to use polymorphism... regardless of how you choose to get the type.

I think the problem is I am adding it to a Vector of StaffMember objects. Staff Member is the base class, so would case the derived classes into StaffMember objects?

I took your advice and wrote a GetType() method.
Casual objects return the char 'c'
Manager objects return the char 'm'
StaffMember objects return the char 's'

After adding Casual/Manager objects to the Vector, and then calling the "GetType()" method they all return 's'. So I think they are being type casted.

So maybe the question now is, how do I prevent this type casting from happening.

The vector manipulates the objects as StaffMembers, but in spite of that, they are still objects of the class you created them as, and GetType() should work fine.
If GetType() always returns 's', I wonder if you've forgotten to make it public virtual in the base class?

>>I think the problem is I am adding it to a Vector of StaffMember objects. Staff Member is the base class, so would case the derived classes into StaffMember objects?

Simple:

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

class Base
{
public:
    Base() {x = 0;}
    virtual void Display()= 0;
protected:
    int x;
};

class Derived1 : public Base
{
public:
    Derived1() { x = 1;}
    virtual void Display() { cout << "This is Derived1\n";}
};

class Derived2 : public Base
{
public:
    Derived2() {x = 2;}
    virtual void Display() { cout << "This is Derived2\n";}
};

int main () {
    vector<Base*> theList;
    Derived1 * pD1 = new Derived1;
    theList.push_back(pD1);
    Derived2 * pD2 = new Derived2;
    theList.push_back(pD2);

    vector<Base*>::iterator it;
    for( it = theList.begin(); it != theList.end(); it++)
       (*it)->Display();

}

No compiler to prove this works, but idea behind should be valid.

class staffmember  //declared as abstract base class
{
    private:
       int ID;
       string name;
       char type;
       double wage;
   
    public:
       virtual getID() = 0;
       virtual string getName() = 0;
       virtual char getType() = 0;
       virtual double getWage() = 0;
};

class Manager : public staffmember
{
    public:
      Manager(){type = 'M';} 
      //mutator functions here, left out of this example

      //the following accessor functions are all overridden virtual functions
      int getID() {return ID;}
      string getName() {return name;}
      char getType() {return type;}
      double getWage() {return wage;}
};

//similar for Casual class here

//declare vector of staffmember pointers
vector<staffmember *> employees;

//declare a Manager object
Manager m;

//fill variables of m as needed here
//add m to employees
employees.push_back(&m);

//declare a Casual object
Casual c;
//fill variables of c as needed
//add c to employees;
employees.push_back(&c);

//display employees
int len = employees.size();
for(int i = 0; i < len; ++i)
{
   cout << "employee with index " << i  << ": " << endl;
  employees[i]->getID();
  cout << endl;
  employees[i]->getName();
  cout << endl;
  employees[i]->getType();
  cout << endl;
  employees[i]->getwage();
  cout << endl << endl;
}

Ancient Dragons example is more succinct, and use of iterators is classy, but I don't like the (*it)-> syntax so I used the []. Oh, and he can type faster than I can!

Thanks for posting up the code Ancient Dragon and Lerner. I had something very similar to what you two have written.

MrSpigot was right, I didn't set my getType() function to virtual and as a result every Casual/Manager object returned 's' instead of 'm'/'c'.

So there we go, everything is working now and I thank you.

Angus

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.