C++ inheritance, and hiding unwanted inherited functions - c++

I am trying to implement a QToolBar subclass, which has its items specified by a model, instead of added individually. This means a selection of functions to add/remove items (toolbar buttons), such as addAction shouldn't be publicly accessible.
What is the best way to inherit from this object, but make a selection of functions private?
My current best idea is to do like this:
class ToolbarView : public QToolBar
{
Q_OBJECT
public:
explicit ToolbarView(QWidget *parent = 0);
signals:
public slots:
private:
void addAction (QAction *action) {Q_UNUSED(action)};
QAction* addAction (const QString &text) {return QToolBar::addAction(text) ;}
...
QAction* addSeparator() {QToolBar::addSeparator();}
... [list of about 10 of these]
};
So, redefining all the functions that should not be public, as private.
Is this a good idea, or are there better methods?

As long as you inherit publicly from QToolBar, you make it possible for a client code to treat your object as such and call for example the addAction member function. If you want to ensure that these functions are inaccessible, you'll have do this the other way :
Inherit privately from QToolBar
Publicly expose the functions you wish to expose (for example with using declarations)
If you want to stick with your initial solutions and inherit publicly from QToolbar :
Be aware that it doesn't guarantee base class functions won't be called
You should consider using using declarations to change the accessibility of the base class functions instead of hiding them

Maybe you could think of this
class ToolbarView : private QToolBar
{
//...
}
In such case, all of accessible QToolBar will be with private access in your ToolbarView .

You are publically inheriting from QToolbar. How about changing that to private inheritance. That, is the class definition should begin as
class ToolbarView : private QToolBar
{
// good only if you want to
// make "most" of the public members of QToolBar private in ToolbarView
}

Related

Qt Multiple-inheritance goes wrong

I a project of mine, written in Qt, I have a QWidget Widget that should display either a MyTreeWidget (inheriting from QTreeWidget) or a MyTableWidget (inheriting from QTableWidget)
Constraints
Widget shouldn't know who it is talking to. Therefore it must (??) own a class inherited by the My(Tree|Table)Widget
MyTreeWidget and MyTableWidget share a lot of code and I don't want to copy paste this code. So I thought of making them inherit from a MyGenericView which inherit from QAbstractItemView
The Interfaces
#include <QAbstractItemView>
#include <QTreeWidget>
#include <QTableWidget>
class MyGenericView : public QAbstractItemView
{
Q_OBJECT
public:
MyGenericView();
};
class MyTreeWidget : virtual public QTreeWidget,
virtual public MyGenericView
{
Q_OBJECT
public:
explicit MyTreeWidget(QWidget *parent = 0);
};
class MyTableWidget : public MyGenericView, public QTableWidget { ... };
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0) :
QWidget(parent)
{
m_genericView = new MyTreeWidget();
}
private:
MyGenericView *m_genericView;
};
The Error
erreur : invalid new-expression of abstract class type 'MyTableWidget'
m_genericView = new MyTableWidget();
note: because the following virtual functions are pure within 'MyTableWidget':
class MyTableWidget : public QTableWidget, public MyGenericView
And the same for MyTreeWidget.
So how would you correct this?
It seems that what you're trying to do is ill-advised. Both views that you derive from are convenience views. They hopelessly mix up the view with the model. It's OK to use them if the needs are simple and convenience is all you're after, but in your case I presume most of the shared code is related to the model side of things, not to the view. You could probably achieve what you wish by simply showing a QStandardItemModel on either a stock QTableView or a stock QTreeView, and having a class that uses the QStandardItemModel to build up your data structure.
For more details of how you could do it, if it turned out to be the right thing to do, see this answer.
Edit : As suggested below in comments, this answer is based on faulty assumptions. Please see the better answer below.
First, you have an issue of diamond inheritance. Your error is because MyTableWidget has an undefined pure virtual member function.
Frankly though, I'm not sure why you want to use multiple inheritance at all here. If it's to save on code duplication, why can't MyTreeWidget and MyTableWidget share behavioural elements via composition instead of inheritence? Is this definitely a case of is-a vs has-a? If it's code specific to widgets that is shared but don't overlap in any way with the QTableWidget/QTreeWidget approach, just write an adaptor class that will be filled with either a Tree or Table widget.

Multiple inheritance and interface methods

For several graphic objects I inherit from QGraphicsLineItem, QGraphicsRectItem and so on.
class CustomLine : public QGraphicsLineItem{};
class CustomRect : public QGraphicsRectItem{};
Those objects are added to a container, a custom subclass of a QGraphicsScene "scene" that is meant for displaying and interacting with those items. this->scene->items() returns a list of QGraphicItem's: QList<QGraphicsItem* >
What I want to do is each custom object class to have the same custom interface methods, for example setModeX(). Then I could do stuff like:
Foreach (BaseItem *item, this->scene->items()){
item->setModeX(...);
}
But how do I achieve that?
If I make an interface like
class BaseItem{
public: setModeX(); [...]
private: Mode mode_;
}
and inherit
class CustomLine : public QGraphicsLineItem, BaseItem {};
So while the scene should only contain items based on BaseItem (not sure if this is really needed for this task), I first retrieve a list of objects of one of its 2 base classes, namely QGraphicsItem, and need to cast it to its other base class BaseItem to use the interface methods.
I will probably not be able to cast a CustomLine-item to BaseItem in the loop above, because it does not know about the other base class.
EDIT:
I use MinGW 4.8 32 bit (g++).
I noticed that when I start the foreach-loop, the items in my scene disappear (yet don't see the reason why)
Since scene is a QGraphicsScene, it only consists of QGraphicsItems. So you cannot directly iterate over scene as BaseItems as you show in your code. You have to iterate over each QGraphicsItem. You describe that you could downcast to your CustomLine and then upcast back to a BaseItem, but this only works if you know that all the items in the scene are lines. If scene contains other types of items, your technique would require you to iterate of each kind of item until you found a downcast that worked, and then cast it back to BaseItem.
QGraphicsItem
\ BaseItem
QGraphicsLineItem /
\ /
CustomLine
A simple solution would have been available to you if the Qt library had used virtual inheritance on QGraphicsItem. Then, you would simply need to use virtual inheritance on QGraphicsItem from BaseItem, and then down casting would have worked.
QGraphicsItem
/ \
QGraphicsLineItem BaseItem
\ /
CustomLineItem
Since Qt does not do so, you would either need to make custom changes to the Qt library, or code in your own conversion mechanism.
Assuming you are unwilling to make custom modifications to the Qt library itself, then one approach is to create a mapping between Qt's QGraphicsItem and your BaseItem. The mapping can be done within the constructor of your BaseItem, and undone from BaseItems destructor. To make undoing the mapping more efficient, you can also create a link from the BaseItem to the QGraphicsItem.
class BaseItem {
static std::unordered_map<QGraphicsItem *, BaseItem *> map;
QGraphicsItem *link_;
public:
BaseItem (QGraphicsItem *q) : link_(q) {
//...
map[q] = this;
}
virtual ~BaseItem () {
map.erase(link_);
//...
}
static BaseItem * getBaseItem (QGraphicsItem *q) {
std::unordered_map<QGraphicsItem *, BaseItem *>::iterator i;
if ((i = map.find(q)) == map.end()) return NULL;
return i->second;
}
//...
};
//...
std::unordered_map<QGraphicsItem *, BaseItem *> BaseItem::map;
In your derived classes, you would simply need to pass this to the BaseItem constructor.
class CustomLine : public QGraphicsLineItem, public BaseItem {
public:
CustomLine () : BaseItem(this) {
//...
};
//...
};
And then your loop would use the static BaseItem::getBaseItem() function to convert from a QGraphicsItem pointer to a BaseItem pointer. Thus, since there is no way to create a useable inheritance relationship between QGraphicsItem and BaseItem, their relationship is recorded in a table.
QGraphicsItem <-----------------. link
\ BaseItem <--' map
QGraphicsLineItem /
\ /
CustomLine
Should work just fine, but remember to declare the interface methods virtual in the base class, at least if you want polymorphic behavior.
Declare the functions that you want to exist in every derived class as virtual in the base class. A function that is defined as virtual in the base class can give a default implementation, but derived classes are free to override that implementation and provide their own. You can also declare that function "purely virtual" which means derived classes MUST provide an implementation for that particular function.
In either case, when calling that function on an instantiated object pointed to by a pointer of the base class, it will notice that the base class declared the function to be virtual and use a virtual table (vtable) to find which function to call (As in the base class' definition of the function, if it exists, or the derived classes version of the function).
It seems like there are some constraints on your problem that make this more of an issue than it should be. If you can't control the underlying pointers in your scene, but you know that each of those items inherits from BaseItem, then you can do a cast inside your for loop.
For instance, using the structure you have above:
Foreach (QGraphicsItem *item, this->scene){
((BaseItem*) item)->setModeX(...);
}
Of course, this is only if you can guarantee that the objects in your scene are derived from BaseItem.
CRTP to the rescue:
template <class D> class Base {
D& m_d;
public:
Base(D& derived) : m_d(d) { ... }
...
};
class CustomLine : public QGraphicsLine, Base<CustomLine> {
...
CustomLine() : Base(*this) { ... }
};

Initialize uncopyable third-party base class, with pointer to object

I'm fighting with Qt. Cannot find out reliable solution for my specific problem.
We have custom class MyWidget that must:
be derived from QWidget to override closeEvent method
have fields that must be initialzed in constructor
Problems:
QWidget's guts initialized with QUiLoader from .ui file. So I have only QWidget* pointer
QWidget is non-copyable.
QWidget has no move constructor
The code (error checking and memory management are omitted for simplicity):
class MyWidget : public QWidget
{
bool m_Closed;
public:
MyWidget(QWidget* qw) :
QWidget(*qw), // error: copy constructor is private
m_Closed(false)
{}
bool IsClosed() const { return m_Closed; }
virtual void closeEvent(QCloseEvent *) override { m_Closed = true; }
};
QFile file("main.ui");
QUiLoader uiLoader;
MyWidget* uiMain = new MyWidget(uiLoader.load(&file));
uiMain->show();
Questions:
How can I workaround this? I feel that solution is very simple.
Can I use move semantics here somehow?
Note that:
I cannot make QWidget member, as I need to override its method.
Probably, I can make some MyWidget::Init() method, to init those bool flag, which must be called after each instantiation. But I find this solution unreliable.
In the end, I must just have QWidget, that I can check if it was closed or not (maybe you know another, simple way)
I use MSVC 2013 RC and GCC 4.8.1, so C++11 solution would be great
Do not hesitate, I appreciate any suggestions and criticism.
.ui files can use custom classes that derive from QWidget, so you can use your class in the Designer - even without writing any Designer plugins (it won't be shown). Right-click on a widget and select "Promote".
You need to create your own derived version of QUiLoader, and provide an implementation of the factory method QUiLoader::createWidget that can create your widgets. See this answer for a complete example.
Then you put your initialization code in the derived widget.

Composition pattern

How should one approach composition instead of inheritance? Consider the following class:
class GameObject {...};
class Sprite {
public:
void changeImage(...);
};
class VisibleGameObject: public Sprite, public GameObject {};
class VisibleGameObject : public GameObject {
protected:
Sprite m_sprite;
};
The first VisibleGameObject class uses inheritance. Multiple inheritance. Does not looks good. Second one is what i would like to use, but it won't allow me to access Sprite's API like this:
VisibleGameObject man;
man.changeImage();
How can that be accomplished without inheritance (or code duplication)?
EDIT:
I do know I can just use inheritance or make m_sprite a public member and I can't access the Sprite class because it's private. That's the point, the question is about the best way to change a VisibleGameObject's Sprite, following the rules of data encapsulation.
I think you are still one step behing "composition over inheritance" mindset. The base class should know what to composite. To change image, you should change sprite instance, you shouldn't provide interface of composed instances. For example:
class GameObject {
public:
// you can choose public access or getters and setters, it's your choice
Sprite sprite;
PhysicalBody body;
};
object = GameObject();
object.sprite = graphicalSystem.getSpriteFromImage("image.png");
// or if you prefer setters and getters
object.setSprite(sprite);
More generally GameObject should contain instances (or pointers to instances, depends on your implementation) of base class Component. It makes sense to use inheritance in this case, because this way they can be in one storage like std::map. For example:
class Component {
// ...
};
class Sprite : public Component {
//...
};
class PhysicalBody : public Component {
//...
};
class GameObject {
protected:
std::map<std::string, Component*> components;
//...
public:
Component* getComponent(const std::string& name) const;
void setComponent(const std::string& name, Component* component);
//...
};
For component creation and rendering in main loop use Systems. For example GraphicalSystem knows all instances of Sprite it has created and while rendering it renders only sprites attached to some GameObject instance. Detached component can be garbage collected. Information about position and size might be part of the GameObject or it might be a component "physical".
The best way to understand it is to write your own prototype or to check existing implementations (Artemis, Unity 3D and many others). For more information see Cowboy programming: Evolve Your Hierarchy or try to find Entity/component system.
First of all, the alternative for composition is private inheritance (and not public one) since both model a has-a relationship.
The important question is how can we expose Sprite public members (e.g. changeImage) to VisibleGameObject clients? I present the 4 methods that I know:
(Private) inheritance
I understand that you want to avoid (multiple) inheritance, but for the sake of completeness, I present one suggestion based on private inheritance:
class VisibleGameObject: private Sprite, public GameObject {
...
};
In this case VisibleGameObject privately derives from Sprite. Then users of former cannot access any member of the latter (as if it it were a private member). In particular, Sprite's public and protected members are hidden to VisibleGameObject clients.
Had the inheritance been public, then all Sprite's public and protected members would be exposed by VisibleGameObject to its clients. With private inheritance we have a finer control of which methods should be exposed through using declarations. For instance, this exposes Sprite::changeImage:
class VisibleGameObject1: private Sprite, public GameObject {
public:
using Sprite::changeImage;
...
};
Forwarding methods
We can give to VisibleGameObject public methods that forward the call to m_sprite as show below.
class VisibleGameObject2: public GameObject {
public:
void changeImage() {
m_sprite.changeImage();
}
private:
Sprite m_sprite;
...
};
I believe this is the best design, especially as far as encapsulation is concerned. However, it might require a lot of typing in respect to other alternatives.
Structure dereference operator
Even plain old C provides types that exposes another type's interface as if it was its own: pointers.
Indeed, suppose that p is of type Sprite*. Then by using the structure dereference operator -> we can access members of Sprite (pointed by p) as shown below.
p->changeImage();
C++ allows us to endow classes with customised struct dereference operators (a feature well used by smart pointers). Our example becomes:
class VisibleGameObject3 : public GameObject {
public:
Sprite* operator ->() {
return &m_sprite;
}
private:
Sprite m_sprite;
...
};
and
VisibleGameObject v;
v->changeImage();
Although convenient, this method has many flaws:
As for public inheritance, this approach doesn't give a fine control over which Sprite public members should be exposed.
It works only for one member (that is, you cannot use the same trick to expose two members interfaces).
It messes up with the interface. Indeed, consider for instance that VisualGameObject has a method doSomething(). Then, to call this method on an object v one should do v.doSomething() whereas to call changeImage() one should uses v->changeImage(). This is confusing.
It makes VisibleGameInterface to look like a smart pointer. This is semantically wrong!
C++11 Wrapper Pattern
Finally, there's Sutter's C++11 Wrapper Pattern (watch his presentation, specifically the second slide of page 9):
class VisibleGameObject4 : public GameObject {
private:
Sprite m_sprite;
public:
template <typename F>
auto operator()(F f) -> decltype(f(m_sprite)) {
return f(m_sprite);
}
};
Clients use it this way:
VisibleGameObject4 v4;
v4( [](Sprite& s) { return s.changeImage(); } );
As we can see, compared to the forwarding methods approach this transfer the burden of typing from the class writter to the class clients.
It looks like you are trying to directly access Sprite's function without referencing it first. Try this:
man.m_sprite.changeImage() ;
Note that m_sprite and changeImage() should be public for you to do this. Otherwise use a public accessor function to manipulate private class members.

How to access members of wrapper class from member which is wrapped in class

For ex. I got:
"wrapper.h"
class wrapper : public QWidget
{
Q_OBJECT
public:
Wrapped_class m_class;
private:
QTimer* m_timer;
}
"Wrapped_class.h"
class Wrapped_class
{
public:
Wrapped_class();
public slots:
f(); // slot which is called when m_timer send signal timeout()
}
"Wrapped_class.cpp"
Wrapped_class::Wrapped_class()
{
QOBject::connect(wrapper::m_timer, SIGNAL(timeout()), this, SLOT( f()))
}
I get error that wrapper::m_timer in not accessible
You need a pointer or reference to the class to access it's non static members. Pass a pointer to the wrapped class when it's being wrapped
add something like this to your Wrapped_class:
void Wrapped_class::setWrapper(wrapper *w)
{
m_wrapper = w;
}
and call this function when the object is being wrapped. Initialize m_rapper to nullptr in constructor
Depending on your intent and the design of your system, you can choose:
Pass a pointer or reference of "wrapper" class to "wrapped" class. Be ware, you have to define wrapper class as a friend in order to access private member.
Write a member function of "wrapper" class to deal with the interaction between two classes. (This does not really conform to your restriction, but it is a design alternative.)
m_timer is not a static member so you cant access it like that. In Wrapped_class.cpp you need the instance of wrapped class to use it
Besides the problem with wrapper::m_timer not being static, it is also private which means that Wrapped_class can't access it. You need to make Wrapped_class a friend of wrapper for it to access private members.