Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

polymorphism and virtual functions

Status
Not open for further replies.

corpse

Programmer
Dec 26, 2003
3
0
0
BE
Say I have the following classes:
(I left out constructors and destructors as they don't matter here)

class Employee{
public:
virtual void pay()=0;
}
class Worker{
int age;
public:
void pay(){
cout<<&quot;pay worker&quot;;
}
void setAge(int a){age=a;}
}
class Manager{
public:
void pay(){
cout<<&quot;pay manager&quot;;
}
}

Now I create a map:

typedef map<string, Employee*> employees;
employees m;

and insert a few:

m.insert(pair<string, Employee*>(&quot;George&quot;,(new Worker())));
m.insert(pair<string, Employee*>(&quot;Bush&quot;,(new Manager())));

now I can use an Iterator to go through every item in the map and call:
(map_iter->second)->pay();

But, and here comes my question, how can I in a general and clean way do something similar like:
(map_iter->second)->setAge();

Certainly this should only be applied to the workers and not to the managers.

Off course you could make the function &quot;setAge()&quot; a virtual function in class Employee, but isn't there another way to use some kind of dynamic typechecking??
 
Search MSDN for 'Run-Time Type Information'

/JOlesen
 
First of all , decide the inheritance between your classes.
The solution is to derive Employee from CObject and after that decide about Worker and Manager how are derived from Employee or something else.
With that your virtual pay() will work as you want and you know about the polymorphysm.
For the second question , setAge() use : RUNTIME_CLASS macro as in this example:
Worker w1;
Employee *pEmployee = &w1; // Worker is assumed derived if ( pEmployee->IsKindOf(RUNTIME_CLASS(Worker)) )
pEmployee->setAge();

-obislavu-
 
Thanks for the replies. I will try them tomorrow
 
If you want to use something closer to the real C++ standard, and not some Microsoft-specific RTTI, look up the dynamic_cast operator. It is used to cast a base class pointer to a derived class pointer. You don't need an extra CObject base class or the RUNTIME_CLASS macro. You just need to turn on RTTI in the compiler settings.

If the object is not of the derived class, the pointer is set to NULL automatically. You can check for this in your code right after the cast, to determine if the object really supports the derived class method or not.
 
Just to add to teriviret's response, here is an example of how you might do this:
Code:
class Employee{
public:
  virtual void pay()=0;
};
class Worker : public Employee {
  int age;
public:
  void pay(){
    cout<<&quot;pay worker&quot;;
  }
  void setAge(int a){age=a;}
};
class Manager : public Employee {
public:
  void pay(){
    cout<<&quot;pay manager&quot;;
  }
};

...

Worker* pWorker = dynamic_cast<Worker*>(map_iter->second);
if (pWorker){
  pWorker->setAge(30);
}
 
Thanks, I got it working with RTTI. Just the way like you said above.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top