switch by type_id (using RTTI)
-
I have multiple derived classes and a function that accepts their (abstract) base ptr. Right now I have a lot of code like this in my function:
void foo(BaseClass* p)
{
if (DerivedClass1 *p1 = dynamic_cast<DerivedClass1 *>(p))
{
...;
}
else if(DerivedClass2 *p2 = dynamic_cast<DerivedClass2 *>(p))
{
...;
}
}I want to replace it with a switch if possible:
switch (p.type_id)
{
case DerivedClass1.type_id: ...; break;
case DerivedClass2.type_id: ...; break;
}is that possible to do?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
-
I have multiple derived classes and a function that accepts their (abstract) base ptr. Right now I have a lot of code like this in my function:
void foo(BaseClass* p)
{
if (DerivedClass1 *p1 = dynamic_cast<DerivedClass1 *>(p))
{
...;
}
else if(DerivedClass2 *p2 = dynamic_cast<DerivedClass2 *>(p))
{
...;
}
}I want to replace it with a switch if possible:
switch (p.type_id)
{
case DerivedClass1.type_id: ...; break;
case DerivedClass2.type_id: ...; break;
}is that possible to do?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
Derived class ids
#define ID_DER1 01
#define ID_DER2 02in base class, add a pure virtual function
virtual int GetTypeId() = 0;
its implementation in derived classes
int DerivedClass1::GetTypeId()
{ return ID_DER1; }int DerivedClass2::GetTypeId()
{ return ID_DER2; }and the foo function looks like
void foo(BaseClass* p)
{switch (p->GetTypeID()) { case ID\_DER1: printf("der1"); break; case ID\_DER2: printf("der2"); break; }
}
-
I have multiple derived classes and a function that accepts their (abstract) base ptr. Right now I have a lot of code like this in my function:
void foo(BaseClass* p)
{
if (DerivedClass1 *p1 = dynamic_cast<DerivedClass1 *>(p))
{
...;
}
else if(DerivedClass2 *p2 = dynamic_cast<DerivedClass2 *>(p))
{
...;
}
}I want to replace it with a switch if possible:
switch (p.type_id)
{
case DerivedClass1.type_id: ...; break;
case DerivedClass2.type_id: ...; break;
}is that possible to do?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
As far as I know, it's not possible. However, your code doesn't seems very nice: you are really breaking some basic principle of OOP. Why do you need to access the specific types ? Can't you instead use virtual functions and let each type implements the expected behavior as needed ?
Cédric Moonen Software developer
Charting control [v3.0] OpenGL game tutorial in C++ -
As far as I know, it's not possible. However, your code doesn't seems very nice: you are really breaking some basic principle of OOP. Why do you need to access the specific types ? Can't you instead use virtual functions and let each type implements the expected behavior as needed ?
Cédric Moonen Software developer
Charting control [v3.0] OpenGL game tutorial in C++I use this to pass notification messages for progress updates, task finished, etc. from worker threads. I use it instead of callbacks. Some messages need their own userdata (hence derived classes, which contain the userdata). I could use callbacks with void* pParam for the userdata, and an ID to show the type of message (like PostMessage does), but RTTI already gives me the ID. The receiver of the message is not always derived from CWnd (otherwise I would have just used PostMessage instead of this whole thing).
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
-
I use this to pass notification messages for progress updates, task finished, etc. from worker threads. I use it instead of callbacks. Some messages need their own userdata (hence derived classes, which contain the userdata). I could use callbacks with void* pParam for the userdata, and an ID to show the type of message (like PostMessage does), but RTTI already gives me the ID. The receiver of the message is not always derived from CWnd (otherwise I would have just used PostMessage instead of this whole thing).
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
I still don't really understand what you need to do differently for the different types :confused:. If these are some kind of "typed" messages, can't you just provide a virtual getText method that is overriden by each type ? I really don't understand your scenario: what are those objects and why do you need to handle them differently based on their types ?
Cédric Moonen Software developer
Charting control [v3.0] OpenGL game tutorial in C++ -
I have multiple derived classes and a function that accepts their (abstract) base ptr. Right now I have a lot of code like this in my function:
void foo(BaseClass* p)
{
if (DerivedClass1 *p1 = dynamic_cast<DerivedClass1 *>(p))
{
...;
}
else if(DerivedClass2 *p2 = dynamic_cast<DerivedClass2 *>(p))
{
...;
}
}I want to replace it with a switch if possible:
switch (p.type_id)
{
case DerivedClass1.type_id: ...; break;
case DerivedClass2.type_id: ...; break;
}is that possible to do?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition. Blaise Pascal
Quick Question: What does switching on a type mean... especially if you're dynamically casting the result? Answer: It means you're missing a virtual function! So don't mess about with switches and casting, add a virtual function to the base class. This will give you three benefits: - SPEEEEED - a virtual function call will always as fast or faster than a switch on a type_id - It makes your code a lot easier to read. Your switch/if/then else is replaced by 1 line, yep - It makes your code a lot easier to extend. If/when you add a new derived class you just have to implement the derived class, you don't have to mess about with the client code. SO... Just say no to switching on type_id. You know it makes sense. Cheers, Ash
-
Quick Question: What does switching on a type mean... especially if you're dynamically casting the result? Answer: It means you're missing a virtual function! So don't mess about with switches and casting, add a virtual function to the base class. This will give you three benefits: - SPEEEEED - a virtual function call will always as fast or faster than a switch on a type_id - It makes your code a lot easier to read. Your switch/if/then else is replaced by 1 line, yep - It makes your code a lot easier to extend. If/when you add a new derived class you just have to implement the derived class, you don't have to mess about with the client code. SO... Just say no to switching on type_id. You know it makes sense. Cheers, Ash
Couldn't agree more :)
Cédric Moonen Software developer
Charting control [v3.0] OpenGL game tutorial in C++