I have no clue how to properly solve this problem:
I have a container class called CONTROL
and i have derived classes EDIT, LABEL, BUTTON etc.
now in my class WINDOW there is a list of CONTROLs like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class CONTROL_LIST
{
public:
CONTROL*head;
CONTROL*current;
void init();
bool empty();
void add(CONTROL* element);
};
class MAIN : public windows
{
public:
CONTROL_LIST controls;
[...]
CONTROL* getById(int a);
} document;
the method getById goes through the list of CONTROLs (EDITs, LABELs and BUTTONs linked together via pointers) and returns a CONTROL* when it finds the EDIT or LABEL or BUTTON holding the corresponding 'int a'.
There is no problem so far.
The getById method returns a valid CONTROL* but when i try to access a method unique for a LABEL object (one which is not contained in the CONTROL class) using that pointer of course the compiler would throw out an error
"class CONTROL has no member named 'unique_LABEL_class_member'"
Is there any possibility to access 'unique_LABEL_class_member' (or any other derived class member) using a CONTROL* without making 'unique_LABEL_class_member' a member of the CONTROL class?
Of course this will crash if the CONTROL is not actually the base of a LABEL instance. You must have some way of verifying that the control is actually a label in order to do this safely.
Although it hints that you have some sort of design problem if you need members in LABEL but you only take a CONTROL*. If you need a LABEL* somewhere, then you might be better off not using polymorphism in this case.
Oh btw, CONTROL_LIST could easily be replaced by std::list<CONTROL>
I would say don't use dynamic_cast. It would be better to implement your own RTTI than using the built in RTTI. The built in RTTI has to cover every case that can arise, resulting in much more complicated code, especially if you have more than one level of inheritance.
On the other hand you know exactly in what ways you're going to be using the RTTI, so you can suit it to fit that, with minimal code.
For example, it could be as simple as adding a "classType" member to the CONTROL base, which other controls assign to in their constructors, so that you can identify what a CONTROL is by reading that class property.
@stravant
static_cast works ;) thank you very much
@firedraco
so do you suggest to make an own list for every derived class? i tried to use CONTROL as a container just to make it more convenient.
thanks for the hint about std::list ill have a look at that
@denis
i think static_cast will suffice but thanks anyways ^^
@stravant
if i add such a classType member i still need to do the casting though, right?