Can this be done with multiple inheritance? - c++

Here is what I would like to do.
Say I have Class Widget.
I then create Button from Widget.
I then create ModifiedWidget which re-implements certain functions of Widget.
I then want Button to use ModifiedWidget rather than plain Widget. Is this possible to do some how?
Thanks
class Button : public Widget;
class SuperButton : public Button, public ModifiedWidget;
I'm just not sure if that would do what I want it to though.

The easiest way is to use encapsulation, not inheritance.
class Button
{
Button(Widget * w) { mywidget = w; }
Widget * mywidget;
};
Another way is to let Button be a template class.
template<class Parent>
class Button : Parent
{
};
Button<Widget> mybutton1;
Button<ModifiedWidget> mybutton2;

Keep them separate:
class Widget {
...
virtual void some_function();
};
class ModifiedWidget : public Widget {
...
// override the base version of this method
virtual void some_function();
};
class Button {
Button(Widget* w) : widge(w) { }
Widget* widge;
};
class SuperButton : public virtual Button {
SuperButton(Widget* w) : Button(w) { }
};
Now your Widgets have a hierarchy, and your Buttons have their own hierarchy. And it probably makes more sense to say that your Button contains a Widget, than to say that your Button is a Widget. Thus, we go with encapsulation instead of inheritance for the Button-Widget relationship, but still have inheritance for the Buttons and Widgets separately.

If I have understood your question, this is typical Dreaded Diamond Problem
With some care, it is possible, although I suggest reconsidering your design, because multiple inheritance can be often avoided (which brings simpler and cleaner design).
Also Read C++ Faq on Dreaded Diamond
In reply to your example, you will have to use virtual inheritance for Button and ModifiedWidget classes.
class Button : public virtual Widget;
class ModifiedWidget : public virtual Widget;

Related

C++ - Is there any way to avoid diamond form built in class?

Is there any way to avoid diamond problem form built in a class where I can't inherit virtually like below?
class Widget
{
// Built in class can't be modified
public:
bool draw();
};
class Button : public Widget
{
// Built in class can't be modified
// Not able to put virtual inheritance for Widget Class
};
class MyOwnSpecialWidget : public Widget
{
// Some special treatment for non container widgets
};
class CustomButton : public Button, public MyOwnSpecialWidget
{
// So here the copy of Widget is coming form both Button
// and MyOwnSpecialWidget class.
};
So, what is the way to get only one copy of Widget class in CustomButton class?

C++ Qt program design issue

In C++ Qt there is a class QWidget
class A inherits QWidget and adds some features
class B inherits A and adds some features
class C inherits B and adds some features, C must be of type QWidget and should do all things done by B
For some reason C is not behaving as expected, I have to rewrite class C. I can not modify code up to class B creation.
How can I solve this problem? Any design pattern, or anything else?
If I try to inherit QWidget and B, a multiple inheritance, there will be two QWidget which leads to problem (QObject - moc does not allow it).
If I inherit from QWidget and pass object of B to C's constructor, whatever operation B performs applies to another QWidget coming through B, which is not desired, all features provided by B should apply to my C's QWidget.
Suppose there is a temperature sensor, when that gets disconnected from machine, class B draws a content blocker image on the whole area of QWidget that it owns, I can monitor sensor connect /disconnect and suppose C's fun. OnDisconnect() gets called, I will call B::OnDisconnect(), B will draw blocker image on its own QWidget, not on the one which is owned by C.
This has everything to do with C++'s rather inflexible method implementation inheritance when compared e.g. to the Common LISP Object System.
Since B's obscuration is always meant to be on top of B's contents, what you effectively need is for B to provide an overlay that draws on top of its contents, even if paintEvent is overriden in derived classes.
See this answer for a simple example, or another answer for an overlay with blur graphical effect.
This is fairly easy to accomplish by having B add an optional overlay widget to itself.
Example:
class OverlayWidget; // from https://stackoverflow.com/a/19367454/1329652
class ObscureOverlay : public OverlayWidget
{
public:
ObscureOverlay(QWidget * parent = {}) : OverlayWidget{parent} {}
protected:
void paintEvent(QPaintEvent *) override {
QPainter p{this};
p.fillRect(rect(), {Qt::black});
}
};
class A : public QWidget {
...
protected:
void paintEvent(QPaintEvent *) override { ... }
};
class B : public A {
...
ObscureOverlay m_obscure{this};
public:
B() {
m_obscure.hide();
}
Q_SLOT void OnDisconnect() {
m_obscure.show();
...
}
};
class C : public B {
...
protected:
void paintEvent(QPaintEvent * event) override {
B::paintEvent(event);
...
}
};
If you don't have the source code to B, you can add the overlay to C, replicating original B's functionality when obscured. All of Qt's slots are effectively virtual, so if you pass a C to someone expecting B and connecting to its OnDisconnect slot, it will be C's slot that will get invoked.
class C : public B {
Q_OBJECT
...
ObscureOverlay m_obscure{this};
public:
explicit C(QWidget * parent = {}) : B{parent} {
m_obscure.hide();
}
Q_SLOT void OnDisconnect() { // slots are effectively virtual
m_obscure.show();
B::OnDisconnect();
}
protected:
void paintEvent(QPaintEvent * event) override {
B::paintEvent(event);
QPainter p{this};
...
}
};

Add functionality to class and all of it's subclasses

I have 3 classes that inherit from 3 different classes which all inherit from QWidget base class.
For example:
MyMainWindow : public QMainWindow : public QWidget
MyPushButton : public QPushButton : public QWidget
MyTextEdit : public QTextEdit : public QWidget
And I will have more classes like this eventually.
What I'd like to do now, is add a common method to all my classes; this means it should be added to the QWidget base class, but I can't edit it (I'd rather not change the Qt source code for one method).
Is this kind of behaviour possible?
I've already tried using interfaces like so:
class MyTextEdit : public QTextEdit, IMyMethodContainer { ... };
But the problem is, I need to access QObject::connect(sender, signal, this, slot); in IMyMethodContainer, and by this I'm trying to access the MyTextEdit, not the IMyMethodContainer, which is not a subclass of QWidget.
CRTP might help.
template<typename Derived, typename Base>
struct InjectMethod: Base {
static_assert( std::is_base_of< InjectMethod<Derived,Base>, Derived >::value, "CRTP violation" );
Derived* self() { return static_cast<Derived*>(this); }
Derived const* self() const { return static_cast<Derived*>(this); }
void my_method() {
// use self() inside this method to access your Derived state
}
};
Then:
class MyTextEdit: InjectMethod< MyTextEdit, QTextEdit > {
};
class MyPushButton: InjectMethod< MyPushButton, QPushButton > {
};
inside InjectMethod< MyTextEdit, QTextEdit > you have access to a self() pointer that has access to all stuff inside MyTextEdit, and inside InjectMethod< MyPushButton, QPushButton > the same.
You may not need the Derived portion -- possibly having a single template parameter (your base) would be enough, if you only use QWidget functionality.
In Java you can "extend" QWidget and add your custom methods there.
Class MyQWidgetExtension extends QWidget { ... }
Your other classes (QMainWindow, QpushButton, QtextEdit) just extend ("inherit") from that. Is there similar for C++?
Class MyQWidgetExtension : public QWidget { ... }

How to separate hierarchical data and GUI?

I heard that it is better to separate data and GUI. For examples, I have some data. It is hierarchical with abstract base and derived class for concrete types, like
class Data {};
class ConcreteDataA : public Data {};
class ConcreteDataB : public Data {};
And I also have its hierarchical GUI (for example dialog)
class DataDialog {};
class ConcreteDataADialog : public DataDialog {};
class ConcreteDataBDilaog : public DataDialog {};
And I want create a data dialog object from a data object. If the data object is ConcreteDataA, ConcreteDataADialog is created, if B, B dialog is created. There is an easy way to do it by adding a virtual function in class Data like
virtual DataDialog* CreateDialog()
But if I add this function in the data class. it seems to violate the data/GUI separation principle. The second way is to build a global CreateDialog function, and create dialogs according to the dynamic_cast type of data object. This way is also not good for many maual ifs. Any other way to implement it? Or in practice, the first way is also okay? Thanks a lot!
One of my friends told me to use reflection. I think this should work.
It seems that you're looking for an Abstract Factory.
An Abstract Factory is a design pattern in which different types of objects can be created depending on the argument. So in this example, the factory will create a ConcreteDataADialog or a ConcreteDataBDilaog depending on the type of the data.
Code sketch:
class DialogFactory {
public:
virtual Dialog* createDialog() = 0;
};
class ADialogFactory : public DialogFactory {
public:
Dialog* createDialog() {
return new ADialog();
}
};
class BDialogFactory : public DialogFactory {
public:
Dialog* createDialog() {
return new BDialog();
}
};
class Application {
Dialog* createSpecificDialog(Data data) {
if (data.isA()) {
return new ADialogFactory().createDialog();
} else {
return new BDialogFactory().createDialog();
}
}

Initializing the base class to a derived base class?

I don't think this is possible, but if it is, I'd find it very usseful.
I'm making a Gui API where the user does the paint event. Lets say I want to make a Numeric TextBox. Well it would only seem good practice for it to inherit from TextBox. The problem with this, is that the user is then stuck to reimplement the paint event for the textbox since
TextBox::paint();
Would just call my default way of drawing it.
It would be annoying if they had to maintain all their TextBox derivatives.
Is there a way to get around this problem?
Lets say my TextBox paints a square, then the numeric part adds a circle, but the user's textbox, which derives from my TextBox draws a triangle, and my Numeric one derives from my TextBox I want the result to be triangle, circle.
Thanks
As I say in my comment, I think the bridge pattern is actually what you want, but since you're trying to insert a user's class as a base class for your NumericField thing the way you'd do THAT is to:
template < typename Base = TextField >
struct NumericField : Base
{
...
void paint() { Base::paint(); draw_circle(); }
};
Now the user could use NumericField<> or they could insert their class:
struct UserField : TextField
{
...
void paint() { draw_triangle(); }
};
NumericField<UserField> my_field;
The bridge answer would look more like so:
struct TextField
{
TextField() : extender_(new null_extender) {}
...
void set_extender(extender*);
virtual void paint() { draw_square(); extender_->paint(); }
...
};
struct extender { virtual void paint() = 0; };
struct null_extender { void paint() {}};
struct numeric_extender { void paint() { draw_circle(); }};
struct UserField
{
void paint() { draw_triangle(); extender()->paint(); }
};
Lots of details missing from that, but that would sort of be the story.
Isn't the only difference between NumericTextBox and TextBox that the former only allows the input of certain characters? Do you want it to paint differently?
I'm not sure quite what you mean. Your question is not that clear.
The title seems to be asking how to call the base class initializer or constructor,
is that what you want?
If this is what you want then just like this.
class TextBox
{
public:
TextBox() { }
virtual ~TextBox() { }
virtual Paint() { }
};
class NumericTextBox : public TextBox
{
public:
NumericTextBox() : TextBox() { }
~NumericTextBox() { }
};
Make sure the base class for TextBox::Paint and any other methods are declared virtual as well as the destructor.