Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to dynamic_cast in class hierarchy

I have a class structure with loads of different child classes all inheriting from the same abstract base class. This base class is there because all these classes self register at compile time to a factory from which they are built. This is really neat and keeps me from the burden of maintaining a huge switch or any other flow mechanism somewhere down stream.

              +---------------+
              |     Base      |
              +--+---------+--+
                 |         |
         +-------+-+     +-+-------+
         |  Kid1   |     |  Kid2   |
         +----+----+     +----+----+
              |               |
  +---+---+---+               +---+---+---+
  |   |   |   | ...           |   |   |   | ....

However, these Kid1 and Kid2 classes are different and the issue is that I have to distinguish between them somewhere in my code and the only thing I have is a Base pointer. I did not want to bother the factory with this and keep that as simple as possible.

The way I solved this right now is by having Base being somewhat aware of the two siblings. It has a virtual method type() which returns an enum type distinguishing between Kid1 and Kid2. Both kids override this (basically saying I am KidX) such that I know with whom I am dealing. This type is then used to dynamic_cast Base to either of the kids and the program proceeds.

However, is this the right approach?

I could for example add some more virtual methods to base, on the one hand polluting it with methods only one part of the hierarchy uses but on the other hand saving me the dynamic_cast.

Any thoughts?

like image 457
Montaldo Avatar asked Mar 12 '23 06:03

Montaldo


2 Answers

In multiple inheritance, dynamic_cast will shift the pointer as necessary and is a must. Therefore, getting rid of it is dangerous. If your system extends to a point where it uses MI somewhere down, you might get all sorts of strange behaviour.

like image 152
Cem Kalyoncu Avatar answered Mar 24 '23 05:03

Cem Kalyoncu


You don't need dynamic_cast, dynamic_cast already use internal runtime type information to determine if it's able to cast the passed pointer/reference to the desired type but you are already checking it through the type() method. A static_cast is enough in your situation, as you are already providing RTTI by yourself.

Or alternatively you could just remove the type() method and use directly dynamic_cast, which yields nullptr if it's not able to cast the object to your desired type.

If you really want to avoid such things then you are forced to encapsulate the behavior desired into virtual methods such that wherever you need to use a Kid1 or Kid2, you will have different implementation without the need to really distinguishing between the two, just by letting polymorphism do its work.

like image 36
Jack Avatar answered Mar 24 '23 04:03

Jack