Solved 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.
-
Why do you need multiple inheritance?
-
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!
-
Makes me think of an interface like used for Qt's plugins
-
Inheritance is a representation of is relation. Are you sure
imageDownload
is aprotocol
? 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.
-
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
-