I have a class hierarchy similar to this:
class Widget {
// a lot of virtual members
};
class Button : public Widget {
// new stuff overrides
};
class MySuperButton : public Button {
// ...
};
And I would like to hide the fact that MySuperButton
inherit from Button
, but not from Widget
. Basically making the inheritance from Button
private while keeping all its base classes public.
Why?
I have a complicated widget build on Button
, which needs to maintain some invariant with its button state. Exposing it has a Button
might allow something to
modify the button directly breaking these invariants.
Example:
MySuperButton button;
button.setText("Click me!") // calls Button::setText
// Oh no, MySuperButton set some special text which has now been overriden =(
What doesn't work
Making
MySuperButton
inherit fromButton
privately also hidesWidget
, preventing me from doingWidget
things with my button.Using access specifiers does not prevent
MySuperButton
to be converted into aButton
. Sovoid doButtonStuff(Button& b);
will accept aMySuperButton&
just fine.Using compositon forces me to reimplement a bunch of stuff that
Button
already reinmplements, just to forward it which is a PITA. Especially since the actual hierarchy is rather deep and these are big classes.Virtual inheritance doesn't seem to work as the base isn't visible (not sure why that would be a problem though). See Godbolt
I can not modify the Button
or Widget
classes as they are from an external library (Qt in this case). Also the actual code is somewhat more complicated, the provided hierarchy is for illustration.
Is there any way to do this, or do I need to accept that my widget can be broken if I am not careful ?
CodePudding user response:
What you are asking is not really possible.
A possible Qt-specific solution is the following:
class MySuperButton : public Widget {
public:
MySuperButton () {
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button = new Button());
setLayout(layout);
}
private:
Button *button;
}