Menu

Get correct class type from a Abstract factory

Help
Tonka
2017-04-13
2017-04-13
  • Tonka

    Tonka - 2017-04-13

    Hey Florian,

    I try to convert a abstract factory with pythonqt, the code run, but my return-value is not what i'm expecting.
    Here is a simple version of it

    class MyInterface
    {
        virtual QString getType() const = 0;
        virtual QString getAlias() const = 0;
    }
    
    class MyImpl : public MyInterface
    {
        virtual QString getType() const { return "MyType"; }
        virtual QString getAlias() const { return "testname"; }
    }
    

    The object get instantiated outside and will be added via registerObject. Via getObject it is possible to get the object back by the given type.

    class MyFactory
    {
        std::vector<MyInterface*> m_interfaces;
    
         void registerObject(MyInterface* iInterface)
         {
                    m_interfaces.push_back(iInterface);
         }
         MyInterface* getObject(const QString& iType)
         {
                 // search trough vector and find the object with that key trough getType()
                 return ....;
         }
    }
    
    # python code
    factory = ... # get the factory
    obj = factory.getObject("MyType")
    print(obj.className) # this prints the class name MyInterface, and i only have the method from the interface
    

    I expect that my returned object has all the functions from the impl object, but i only get the interface type and all it's methods.

    Is there anything wrong with the code or is there another step to do?

    Thx in advance
    Tonka

     
  • Florian Link

    Florian Link - 2017-04-13

    Automatic downcasting only works on QObject because PythonQt can find out the derived type of an instance from the metaObject(). So either you have to derive your interface from QObject or you have to provide the downcasting information to the typesystem (for an example, have a look at QEvent and the derived classes in the typesystem). But this means you need to have a getType() method or use dynamic_cast to check the type. Deriving from QObject is the simplest solution.

     
  • Tonka

    Tonka - 2017-04-14

    Oh, good to know. Does PythonQt support Q_GADGET?

     
  • Florian Link

    Florian Link - 2017-04-14

    I am not sure, what was a Q_GADGET? A class with a meta object but it is not derived from QObject?
    It might work but it probably does not support downcasting.

     
  • Tonka

    Tonka - 2017-04-14

    Yes, it's the metasystem in a class without inheriting from QObject. But sure, auto downcasting does not work.
    http://doc.qt.io/qt-5/qobject.html#Q_GADGET

     
  • Tonka

    Tonka - 2017-04-14

    Hey Florian,

    polymorphic-id-expression works great with simple inheritance, but i could not get a workin version if there is a complex inherit-chain. QObject is (at the moment) not an option.

    Here is my modified example

    class MyInterface // polymorphic-base="yes"
    {
        virtual QString getType() const = 0;
        virtual QString getAlias() const = 0;
    }
    
    class MyOtherInterface // polymorphic-id-expression="dynamic_cast&lt;MyOtherInterface*&gt;(%1) != NULL"
    {
        // ...
    }
    
    class MyOtherInterfaceAdapter : public MyOtherInterface
    {
        // ...
    }
    
    class MyImpl : public MyInterfaceAdapter
    {
        virtual QString getType() const { return "MyType"; }
        virtual QString getAlias() const { return "testname"; }
    }
    
    class MyImpl : public MyInterfaceAdapter, MyOtherInterfaceAdapter
    {
       // ...
    }
    

    The object get instantiated outside and will be added via registerObject. Via getObject it is possible to get the object back by the given type.

    class MyFactory
    {
        std::vector<MyInterface*> m_interfaces;
    
         void registerObject(MyInterface* iInterface)
         {
                    m_interfaces.push_back(iInterface);
         }
         MyInterface* getObject(const QString& iType)
         {
                 // search trough vector and find the object with that key trough getType()
                 return ....;
         }
    }
    
    # python code
    factory = ... # get the factory
    obj = factory.getObject("MyType")
    print(obj.className) # this prints the class name MyInterface, and i only have the method from the interface
    

    My hope is that i get also the methods from MyOtherInterface, but i'm not able to make it work with polymorphic-id-expression (as far as i understand is that polymorphic-id-expression is that it is use to identify the object-wrapper itself, but i don't know how the generator put the correct checks into the static void* polymorphichandler_MyInterface function)

    Do you know how i can correctly handle multiple inheritance?

    Thx in advance
    Tonka

     
  • Florian Link

    Florian Link - 2017-04-14

    I think there is no support for downcasting in multiple inheritance... The wrapper generator is focused on Qt, which does not use multiple inheritance much.

     
  • Florian Link

    Florian Link - 2017-04-16

    Hm, can't you make both abstract interfaces polymorphic-base and use the same polymorphic-id-expression? In theory this should cast down to your implementation from both interfaces... But maybe the generator does not support multiple polymorphic-base base classes? Another alternative would be register your own polymorphic casting handler function for both base classes, you can see how such a function needs to look in one of the generated *init.cpp files of the Qt wrappers.
    It basically just casts to the derived type based on some type information and returns a casted pointer and the name of the derived class. The casting is important, because with multiple inheritance the same object has a different pointer when casting from a multiple inherited base class that is not the first in the inhertance list. (due to the memory layout of C++).

     
  • Tonka

    Tonka - 2017-04-18

    Hey Florian,

    i will try the options.

    Thx for the answer

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.