Some background first:
I am working on some legacy code that implements UI interfaces. The code is structured in a way that it has a base class (actually it’s a struct) WinBase which is then derived to all sorts of graphical objects.
WinBase:
- Button
- DialogWin
- (etc...)
- EditWin
WinBase has a member WinBase **children that is used to keep tabs on all of the children of each object. These children are created and destroyed during runtime in the standard new[]/delete[] fashion.
All methods/functions of these objects assume that they are receiving a pointer to a WinBase object, and dynamic_cast<> is used to ensure/validate that the appropriate pointers are being used.
A later change to the code added two more classes/structs (ListBox and TextBox), that are derived from EditWin which in turn is derived from WinBase.
So… I have pointers to WinBase that being casted to ListBox and TextBox. As I said, dynamic_cast<> is used throughout the code, but I am not sure how safe this is when a function like this constructor is called.
TextBox(WinBase *pw,(...));
How safe is it to cast directly from WinBase to ListBox and vice versa (for instance)?
First of all, why would you want to cast a
WinBaseto aListBoxwhen aListBoxis given to a method expecting aWinBase? If you need a cast there, you should re-think the design, as methods expecting theWinBaseshould operate only onWinBase'sinterface.If, and only if,
ListBoxis derived fromWinBase(either directly or indirectly), you can always cast from aListBox*to aWinBase*(or reference), because a ListBox IS AWinBase.Casting the other way around is NOT safe, because you will never know if the
WinBase*you got is actually aListBox*or something else and that calls for trouble. You can of course usedynamic_cast<>to test if it really is aListBox*, but any dynamic cast calls for a review of your design.Especially that kind of down-cast calls for trouble in a constructor, because when you are not getting what you wanted, what is your code supposed to do? Throwing exceptions, as the only way out is not such a good idea and at its best avoided at all (unless you know what you are doing).