Closest solution to multiple inheritance through QObject subclasses - c++

I have multiple QObject subclasses which should act as interface classes and be implemented by (inherited by) some other classes. For example let class A : virtual public QObject and class B : virtual public QObject be interface classes. I need a QDialog object to implement their behavior like: class X: public QDialog, A, B.
Unfortunately I did not read documentation carefully at design time and now I realized two facts:
implementing slots as pure virtual member functions is not possible because moc-generated code will need to call them.
Multiple inheritance is not supported for QObject-derived classes. That's not a diamond thing. It's because moc-generated code can't static_cast a virtual QObject object to a A* via virtual base. (That's what compiler says!)
What is best possible alternative design to which affects code as less as possible? I can think of macro hacks. Maybe a macro in base class (like Q_OBJECT) to copy all members, signals, slots of base to derived class?
Note That's really bad that QObjects can't be inherited multiple times. Isn't?

If you really need to expose QObject member functions through your A and B classes create an abstract base class (i.e. a class with only pure virtual member functions), say AbstractQObject, and re-declare there the QObject member functions you need to expose.
Have A and B derive virtually from AbstractQObject and X from QDialog, A and B.
This should solve the problem you described, but I suspect you would be better off redesigning your code.

Related

Using a function publicly in base class and privately in derived class

I have a function public void myFunction(foo); and public void myFunction(foo, bar); in my parent class. I want these functions included in my derived class, but privately. You can declare it in the derived class' private section by using BaseClass::myFunction(). Note that it doesnt take any parameters in the function. But if there are two implementations of myFunction like I have in my case, it won't work since it can't distinguish between the two functions. How do I implement both functions privately?
Based on what you've said in your comment about your professor's instruction to use inheritance, more than whether it's a good design choice, I think you are expected to use private inheritance.
Private inheritance is a valid feature of C++, but its often not a good design choice. I wont go into that, I'm not recommending it in general, I'll leave you to look it up elsewhere on SO, but also recommend Scott Meyer's books effective C++ & more effective C++ which covers this.
(protected inheritance on the other hand is very unusual)
In your question you seem to be starting from public inheritance and trying to make some inherited functionality private via using. This is a bad design choice as mentioned in comments. It violates the Liskov substitution principle. Since PUBLIC inheritance implies is-a, we can imagine the code that creates a base class reference to an object of the derived type, what then is supposed to happen when we try to call the hidden functionality with that base class reference?
Derived d;
Base& b = d;
b.HiddenFunction(); // calling the function on d even though you thought you hid it
If instead you use private inheritance you can then use using to publicise those privately inherited functions which are safe to expose on the derived class.
class OrderedLinkedList : private LinkedList
{
public:
using LinkedList::ItemCount; // expose some specific base functionality
};
If using doesn't do the job due to overloaded functions, then you can add just those overloads that you want to provide and implement them just by calling the base function. In such cases, if you need to clarify whether to call the base or derived version you can prefix the function name with the class name e.g.
void SomeFunction()
{
// call base version, not this derived version recursively
NameOfBaseClass::SomeFunction();
}
Within the derived class implementation, the public and protected members of the (privately) inherited base class are accessible without the need to do anything like add a using.
Private inheritance is not an is-a relationship like public inheritance since we cannot refer to the derived objects as references/pointers to the base. Private inheritance is "implemented-in-terms-of".
Since private inheritance is not an is-a, one cannot substitute such derived objects for the base and as such the liskov substitution principle just doesn't apply.

Inheritance system leading to ambiguity in Qt

I want to create a inheritance system in one of my Qt applications where there is a QObject derived class "Abstract1" that implements two signals and its derived classes, most of which will be QWidget derived.
The problem is that, the way I'm doing, is leading to "error: 'QObject' is an ambiguous base of " errors. A research on SO revealed the reason for that: I'm including two instance of QObject, one coming from my "Abstract1" class and the other from "QWidget":
class MyNewClass : public Abstract1, public QWidget
My question: how can I avoid the problem but still maintain the structure I want? That is, pure QObject class with the signals and subclasses which include this one and are also QWidget derived?

Is it safe to use *virtual* multiple inheritance if QObject is being derived from DIRECTLY?

I understand that in general, multiple inheritance from QObject-derived classes (even virtual multiple inheritance) is not supported in Qt.
I understand the reason to be (I think) that even in the virtual inheritance case, the Qt classes do not themselves virtually inherit from QObject. For example, if you attempt to derive a class virtually from both QWidget and QThread, this is placing the virtual inheritance in an irrelevant place in the inheritance chain and you still wind up with two QObject instances.
I therefore think it is safe, and supported in Qt, to use virtual inheritance where the ONLY Qt class being derived from is QObject itself.
I have:
class Top : public QObject {};
class Left : public virtual Top {};
class Right : public virtual Top {};
class Bottom : public Left, public Right {}; // Is this safe, and supported by Qt?
Note that instances of Bottom truly have only one instance of Top (and hence only one instance of QObject), so it seems that the rationale for avoiding multiple inheritance in Qt (even virtual multiple inheritance) does not apply here.
The above construct nonetheless results in the Qt compiler warning Class Bottom inherits from two QObject subclasses Left and Right. This is not supported!.
Am I correct? Is it safe to ignore the Qt compiler warning in this specific scenario? Is the above construct, involving virtual multiple inheritance directly from QObject, safe and supported in Qt?
No, multiple inheritance from QObject is not supported by Qt in any way.
The problem is not with virtual inheritance, it's Qt's meta-object system. Each QObject base class has an associated QMetaObject which manages signals, slots, properties, etc, and each meta-object knows its parent QObject so e.g. signals which exist in parent classes can be handled. The Qt moc is not able to deal with multiple inheritance from QObject or any of its sub-classes.

difference between interface inheritance and implementation inheritance

I found those two terms in the book of Meyers, but what is the difference?
Interface inheritance is public inheritance, while implementation inheritance is private inheritance.
If class B publicly inherits from A, B is an A: it inherits the whole interface of A, and a (reference/pointer to) a B object can be automatically be upcasted to A, and used wherever an object of A is expected. However, if B privately inherits from A, B is-implemented-in-terms-of A: only the implementation of A is inherited, not its interface. Thus (references/pointers to) B objects can not be used in places where A objects are expected.
Update
To reflect on #Michal's comment, here are some links (based largely on googling "c++ implementation inheritance") to demonstrate the common usage of these terms in the context of C++:
C++ Design/Coding tips - Part 7
Interfaces
Uses and Abuses of Inheritance, Part 1
Implementation (or class) inheritance is when you separate a common part of implementation in the base class.
Interface inheritance is when you use virtual methods. It is intended to separate interface from implementation and minimize dependencies between program elements.
The major difference is interface is public inheritance and implementation is private inheritance.
The data members and method of the public and protected section will be inherited from base class to derived class in their respective access specifier in public inheritance.At the same time the object of derived class can access the data members of base class as the normal method.
The data members and methods of public and protected section will be inherited from base class to derived class in private access specifier
Here's the difference between the two types of inheritance according to "Taligent's Guide to Designing Programs".
Inheritance
There are two forms of inheritance in C++: type inheritance and implementation inheritance. In both forms of inheritance, a derived class can share or override behavior inherited from a base class. However, use type inheritance only when it is necessary for a derived class to inherit type information as well. The primary reason to inherit type information is to allow for polymorphism.
Express type inheritance by deriving a class from a public base class; express implementation inheritance by deriving a class from a private or protected base class.
More at:
https://root.cern/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_23.html

What is the correct way of Multiple inheritance in Qt/C++?

In my Qt application, I have a base class as follow. I am using QObject because I want to use Signal-Slot mechanism in all derived classes.
class IRzPlugin : public QObject {
public:
virtual void registerMenu(QWidget*);
virtual void execute();
}
Then I have another class as follow. I need to extend from QWidget because I need to implement event handling methods in all derived classes (such as mouseMoveEvent(), keyPressEvent() and others).
class IRzLayeringPlugin : public IRzPlugin , public QWidget{
}
But compiler gives these the errors:
C:\svn\osaka3d\tags\iter08\prototype\osaka3d\rinzo\plugin\moc_IRzLayeringPlugin.cxx: In member function `virtual const QMetaObject* IRzLayeringPlugin::metaObject() const':
C:\svn\osaka3d\tags\iter08\prototype\osaka3d\rinzo\plugin\moc_IRzLayeringPlugin.cxx:51: error: `QObject' is an ambiguous base of `IRzLayeringPlugin'
C:\svn\osaka3d\tags\iter08\prototype\osaka3d\rinzo\plugin\moc_IRzLayeringPlugin.cxx:51: error: `QObject' is an ambiguous base of `IRzLayeringPlugin'
make[2]: *** [CMakeFiles/Rinzo.dir/plugin/moc_IRzLayeringPlugin.cxx.obj] Error 1
In the current incarnation, it isn't possible to use QObject in multiple inheritance paths for a derived class (like your IRzLayeringPlugin class). The only solution I've ever seen was to create an interface class without any QObject inheritence, but with functions that directly correspond to the QObject functions you want to use, then implement the bridge between the interface and your other QObject class inheritance in your specific class. It gets ugly fairly quickly.
There was a similar question today here.
Basically, two things are needed:
Adding Q_DECLARE_INTERFACE after the interface class declaration
Adding the interface to the Q_INTERFACES macro of the class
After this, qobject_cast will work with your interfaces.
If you'd like to use signals and slots from the interfaces, you are out of luck, because you can only do that with types that derive from QObject. But in this case, you would always get the 'QObject' is an ambiguous base of 'IRzLayeringPlugin' error.
In this case, #Caleb's idea is still the best.