问题描述
我正在使用QT的QQuickFramebufferObject
类,该类继承自Qt库中的QQuickItem
.
I'm using QT's QQuickFramebufferObject
class which inherits from QQuickItem
in Qt library.
我有以下用户定义的类:
I have the following user-defined class:
class OpenGlBufferItem: public QQuickFramebufferObject
我还需要我的OpenGlBufferItem
类也要从ReactItem
派生.问题在于,ReactItem
最终也源自QQuickItem
:
And I need my OpenGlBufferItem
class to also derive from ReactItem
. The problem is that ReactItem
ultimately derives from QQuickItem
too:
class ReactItem : public QQuickPaintedItem
因为QQuickPaintedItem
从QQuickItem
所以我们有以下问题:
QQuickItem
/ \
/ \
QQuickPaintedItem QQuickFramebufferObject
/ \
ReactItem OpenGlBufferItem
我需要的是
QQuickItem
/ \
/ \
QQuickPaintedItem QQuickFramebufferObject
/ \
ReactItem /
\ /
\ /
OpenGlBufferItem
通常,为了解决钻石问题,我们只需声明某些类实际上是从其他类继承而来.但是,我无法声明类RectItem
,QQuickPaintedItem
,QQuickFrameBufferObject
,因为它们已经给出.
Normally, to solve diamond problems we'd simply declare some classes as virtually inheriting from others. However, I cannot declare the classes RectItem
, QQuickPaintedItem
, QQuickFrameBufferObject
, because they are already given.
我应该如何进行?
更新:
如果我只是想尝试
class OpenGlBufferItem: public QQuickFramebufferObject, public ReactItem
我遇到了这类错误:
Command failed: ./build.sh -e "modules/mediaplayer/desktop"
In file included from /home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/EWIEGA46WW/moc_OpenGlBufferQtQuick.cpp:9:0,
from /home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/mocs_compilation.cpp:2:
/home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/EWIEGA46WW/../../../../../../../../OpenGlBufferQtQuick.h: In constructor ‘OpenGlBufferItem::OpenGlBufferItem(QQuickItem*)’:
/home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/EWIEGA46WW/../../../../../../../../OpenGlBufferQtQuick.h:90:13: error: reference to ‘connect’ is ambiguous
connect(parent, SIGNAL(widthChanged()), this, SLOT(parentWidthChanged()));
^~~~~~~
In file included from /home/lz/Qt5.11.2/5.11.2/gcc_64/include/QtCore/QObject:1:0,
from /home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/EWIEGA46WW/../../../../../../../../OpenGlBufferQtQuick.h:3,
from /home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/EWIEGA46WW/moc_OpenGlBufferQtQuick.cpp:9,
from /home/lz/orwell/orwellJS/desktop/modules/mediaplayer/desktop/orwell_subdir/orwell_autogen/mocs_compilation.cpp:2:
/home/lz/Qt5.11.2/5.11.2/gcc_64/include/QtCore/qobject.h:308:13: note: candidates are: template<class Func1, class Func2> static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType)
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
^~~~~~~
/home/lz/Qt5.11.2/5.11.2/gcc_64/include/QtCore/qobject.h:300:13: note: template<class Func1, class Func2> static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2)
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
^~~~~~~
/home/lz/Qt5.11.2/5.11.2/gcc_64/include/QtCore/qobject.h:269:13: note: template<class Func1, class Func2> static typename std::enable_if<(((int)(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0) && (! QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction)), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType)
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
^~~~~~~
/
还有很多
推荐答案
这是不可能的.
我当时正在考虑使用CRTP(奇怪地重复使用的模板模式),如果您可以修改其中一个类并可以处理其限制,则可以从理论上使用它.但这不适用于您的情况,因为ReactItem不是直接从QQuickItem派生,而是直接从QQuickPaintedItem派生.
I was thinking about using the CRTP (Curiously Recurring Template Pattern), which could theorhetically be employed if you can modify one of the classes and can handle its restrictions.But it will not work in your case as ReactItem is not deriving directly from QQuickItem, but from QQuickPaintedItem.
让我们假设情况并非如此:
Let's assume that was not the case:
ReactItem需要更改为如下形式:
ReactItem would need to be changed to look like this:
template <class T> class ReactItem : public T {/*...*/};
hiearchy类看起来像这样:
The class hiearchy would look like this:
QQuickItem
/ \
/ QQuickFramebufferObject
/ \
ReactItem<QQuickItem> \
\
ReactItem<QQuickFramebufferObject>
/
OpenGlBufferItem
此方法的局限在于,就类型层次结构而言,两个ReactItem实例是不相关的类型.这意味着以前引用ReactItem
的许多代码可能需要更改.
The restrictions of this approach is, that the two ReactItem instantiations are unrelated types with regards to the type hierarchy.This means a lot of the code previously referring to ReactItem
might needs to be changed.
这对于函数来说很容易做到:
This is quite easy to do for functions:
void f(ReactItem* item) { item->setVisible(true); }
// becomes
template<class T> void f(ReactItem<T>* item) { item->setVisible(true); }
对于像std::vector<ReactItem*>
这样的模板化数据成员而言,这要麻烦得多.
It is a lot trickier for templated data members like std::vector<ReactItem*>
.
这篇关于为Qt类解决此特定的C ++ Diamond问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!