I'm modifying the structure of my project 'imbricable'. The aim is to distinct data and widget. In fact, Each class is composed of many properties. The object can be displayed on a user interface and properties may be changed. To do this, there is a class which is the support of each property. And the object which has a list with properties.
So when the graphical interface displays the content of the object, it goes through the list of properties and display them. To do this the class of property has a method named 'createWidget()' which returns a widget templated by type. For example: 'Data' return a 'TemplatedDataWidget'.
I have always thought it was a mistake, but I haven't smart solution because I have added two other properties mechanisms:
- LinkData: an interface to link an object to another.
- ProcessingData: an interface to define major methods. This one corresponds to a button in the graphical interface which start the method.
Using a templated widget have also a disadvantage: I need to overload methods of the 'TemplatedDataWidget' when I want use a new type, that means a labyrinthine system and a lot of copy-paste code with minor modifications.
These other properties types were overloaded the createWidget() method to create an other widget. The widgets of these types are similar independently than the type.
Initially, I have thought that using a factory hasn't a solution because I didn't know whether key I could have used. Indeed, the factory of the object uses strings as keys (understandable name), because the factory is used when users want to load from XML file or create manually objects but the factory of widgets should be just a GUI mechanism. GUI aspects are less important than register mechanism and using string means to define the name of type for each property. Second point, there is lot of templated Data, LinkData, ProcessingData.
Finally, I have found two choices: using dynamic_cast method to verify if the type corresponds or use std::type_info. And I have decided to use both of them:
- std::type_info in a map for specific properties: it can't be used for inheritance and compares two integers with 'hash_code()' method is faster in a map.
- dynamic_cast: it may concerns inheritance, so adding in the factory a widget for each type is unnecessary and it is possible to group similar cases. This second method to register needs to test each element of the factory.
So I have begun to modify the structure of my program. And when I have tried the new mechanism: this doesn't work. The object is found as BaseData (parent of Data, LinkData and ProcessingData) instead of the real object.
To understand the problem I have created a little project to test typeid() function.
This code return four lines, each one contains the type an object A and object B. Nevertheless, the third and fourth lines are not those expected.
The object pb is a pointer to A but it is set to a pointer to a B object. The expected result of typeid should be B instead of A.
If we can't use typeid in this case, we may think this function is useless: what is the interest of a method which use the current declared type instead of the real one?
In fact, this work only if the parent class has polymorphic methods defined by 'virtual'.
It is no necessary to override the method in the class B. Now the result is correct.
This strange requirement isn't the problem of my project because the BaseData is already an abstract class. So what is the element I missing? just a problem of pointer: "PN10imbricable4core8BaseDataE". grrr