ask moc_xxx.cpp to dynamic cast to achieve polymorphism



  • Hi,

    My purpose is to pass object pointer from one C++ object to another C++ pointer, well, by the help of javascript. Unfortunately, javascript need the parameters to be an object of a class derived from QObject.

    Thus, when doing multiple inherence, I must take advantage of "virtual" keyword when deriving from two classes to avoid ambiguous parent class object. (In my case, QObject is the parent class of two classes derived by "public virtual QObject" )

    But the point is, when moc_xxxx.cpp is generated, the Q_PROPERTY function calls has to cast QObject to the inherited class which allows only dynamic cast.

    So, how to ask QT to do dynamic cast here? Or is there anyway so that javascript accept non-QObject related object?

    Thank you.


  • Moderators

    Why do you need multiple inheritance?


  • Lifetime Qt Champion

    Hi,

    Virtual inheritance of QObject is not supported, see the moc documentation.
    Note that you don't need to have each and every class being a QObject. You can build a QObject wrapper that will talk with objects of your classes as needed.

    Can you show an example of what you are trying to achieve ?



  • Here is what I want to achieve, a swift-like protocol...

    class protocol : public virtual QObject {
        public:
        protocol();
        ~protocol();
        virtual QString printName()=0;
    }
    
    class imageDownload : public virtual fileDownload, public virtual protocol {
    ...
        public:
        virtual QString printName();
    }
    

    If I don't have to pass imageDownload through javascript, class protocol don't have to inherit QObject. But since fileDownload is already inherited QObject, I should be able to pass the object through javascript. But actually, if the object pointer is obtained by casting from QObject ( which is the pointer type I passed to another class), the polymorphism will be lost, that is, there is no result from

    pProtocolObj->printName();
    

    with:

    class protocol {
        public:
        protocol();
        ~protocol();
        virtual QString printName()=0;
    }
    

    In order to achieve polymorphism, I have to virtual inherit QObject. By the way, I cannot pass pointer to imageDownload, because we will lose the "protocol" principle.

    Maybe looking for QObject wrapping is a solution, I will check this out.

    Thanks!


  • Lifetime Qt Champion

    Makes me think of an interface like used for Qt's plugins


  • Moderators

    Inheritance is a representation of is relation. Are you sure imageDownload is a protocol? Wouldn't it make more sense if it had or used a protocol? A way of representing a has relation is by composition, not inheritance i.e.

    class fileDownload {
        ...
        protocol* mProtocol;
    };
    class imageDownload : public fileDownload {
       ...
    };
    

    which is a lot better design (the download class can use any implementation of a protocol) and also avoids the original problem altogether.



  • @Chris-Kawa If imageDownload inherits protocol, then it will be a protocol. The point is I am not able to make it without virtual inheritance.

    If using a "has" relation, a generic algorithm is not able to leverage its owner class. On the other hand, if one class can inherit protocol, then the same algorithm can be applied to whatever class derived by protocol.


  • Moderators

    If imageDownload inherits protocol, then it will be a protocol

    Yes, it will, but what I'm saying is it shouldn't be. Downloading and a protocol sound like two separate functionalities. An object shouldn't "be" both according to Single Responsibility Principle.

    The point is I am not able to make it without virtual inheritance.

    That's true and my point is that you can avoid the problem altogether by using composition instead of inheritance.

    On the other hand, if one class can inherit protocol, then the same algorithm can be applied to whatever class derived by protocol.

    Composition in no way prevents you from that. For example consider extending my previous code:

    void someAlgorithm(protocol* p) { ... }
    
    class superProtocol : public protocol { ... };
    class extraProtocol : public protocol { ... };
    
    fileDownload fd;
    fd.protocol = new superProtocol;
    someAlgorithm(fd.protocol); //works
    
    imageDownload id;
    id.protocol = new extraProtocol;
    someAlgorithm(id.protocol); //still works
    


  • @Chris-Kawa

    Thanks for the explanation, I learn a lot from this.

    Cheers,
    Albus


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.