问题
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 theMy(Tree|Table)Widget
MyTreeWidget
andMyTableWidget
share a lot of code and I don't want to copy paste this code. So I thought of making them inherit from aMyGenericView
which inherit fromQAbstractItemView
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?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/32118815/qt-multiple-inheritance-goes-wrong