C++ instanceof

Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Oct 2008
Posts: 11
Reputation: AnGuRuSO is an unknown quantity at this point 
Solved Threads: 0
AnGuRuSO AnGuRuSO is offline Offline
Newbie Poster

C++ instanceof

 
0
  #1
Mar 30th, 2009
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
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,675
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 261
Lerner Lerner is offline Offline
Posting Virtuoso

Re: C++ instanceof

 
1
  #2
Mar 30th, 2009
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.
Klatu Barada Nikto
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: C++ instanceof

 
0
  #3
Mar 30th, 2009
Here Here!
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 11
Reputation: AnGuRuSO is an unknown quantity at this point 
Solved Threads: 0
AnGuRuSO AnGuRuSO is offline Offline
Newbie Poster

Re: C++ instanceof

 
0
  #4
Mar 30th, 2009
Originally Posted by Lerner View Post
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.
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: C++ instanceof

 
0
  #5
Mar 30th, 2009
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.
Last edited by Comatose; Mar 30th, 2009 at 2:20 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 11
Reputation: AnGuRuSO is an unknown quantity at this point 
Solved Threads: 0
AnGuRuSO AnGuRuSO is offline Offline
Newbie Poster

Re: C++ instanceof

 
0
  #6
Mar 30th, 2009
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.
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 139
Reputation: MrSpigot is on a distinguished road 
Solved Threads: 33
MrSpigot's Avatar
MrSpigot MrSpigot is offline Offline
Junior Poster

Re: C++ instanceof

 
0
  #7
Mar 30th, 2009
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?
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,348
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1462
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: C++ instanceof

 
0
  #8
Mar 30th, 2009
>>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:
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. class Base
  6. {
  7. public:
  8. Base() {x = 0;}
  9. virtual void Display()= 0;
  10. protected:
  11. int x;
  12. };
  13.  
  14. class Derived1 : public Base
  15. {
  16. public:
  17. Derived1() { x = 1;}
  18. virtual void Display() { cout << "This is Derived1\n";}
  19. };
  20.  
  21. class Derived2 : public Base
  22. {
  23. public:
  24. Derived2() {x = 2;}
  25. virtual void Display() { cout << "This is Derived2\n";}
  26. };
  27.  
  28. int main () {
  29. vector<Base*> theList;
  30. Derived1 * pD1 = new Derived1;
  31. theList.push_back(pD1);
  32. Derived2 * pD2 = new Derived2;
  33. theList.push_back(pD2);
  34.  
  35. vector<Base*>::iterator it;
  36. for( it = theList.begin(); it != theList.end(); it++)
  37. (*it)->Display();
  38.  
  39. }
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,675
Reputation: Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all Lerner is a name known to all 
Solved Threads: 261
Lerner Lerner is offline Offline
Posting Virtuoso

Re: C++ instanceof

 
0
  #9
Mar 30th, 2009
No compiler to prove this works, but idea behind should be valid.
  1. class staffmember //declared as abstract base class
  2. {
  3. private:
  4. int ID;
  5. string name;
  6. char type;
  7. double wage;
  8.  
  9. public:
  10. virtual getID() = 0;
  11. virtual string getName() = 0;
  12. virtual char getType() = 0;
  13. virtual double getWage() = 0;
  14. };
  15.  
  16. class Manager : public staffmember
  17. {
  18. public:
  19. Manager(){type = 'M';}
  20. //mutator functions here, left out of this example
  21.  
  22. //the following accessor functions are all overridden virtual functions
  23. int getID() {return ID;}
  24. string getName() {return name;}
  25. char getType() {return type;}
  26. double getWage() {return wage;}
  27. };
  28.  
  29. //similar for Casual class here
  30.  
  31. //declare vector of staffmember pointers
  32. vector<staffmember *> employees;
  33.  
  34. //declare a Manager object
  35. Manager m;
  36.  
  37. //fill variables of m as needed here
  38. //add m to employees
  39. employees.push_back(&m);
  40.  
  41. //declare a Casual object
  42. Casual c;
  43. //fill variables of c as needed
  44. //add c to employees;
  45. employees.push_back(&c);
  46.  
  47. //display employees
  48. int len = employees.size();
  49. for(int i = 0; i < len; ++i)
  50. {
  51. cout << "employee with index " << i << ": " << endl;
  52. employees[i]->getID();
  53. cout << endl;
  54. employees[i]->getName();
  55. cout << endl;
  56. employees[i]->getType();
  57. cout << endl;
  58. employees[i]->getwage();
  59. cout << endl << endl;
  60. }
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!
Klatu Barada Nikto
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 11
Reputation: AnGuRuSO is an unknown quantity at this point 
Solved Threads: 0
AnGuRuSO AnGuRuSO is offline Offline
Newbie Poster

Re: C++ instanceof

 
0
  #10
Mar 31st, 2009
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
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC