为Qt类解决此特定的C ++ Diamond问题 [英] Solving this specific C++ diamond problem for Qt classes

查看:66
本文介绍了为Qt类解决此特定的C ++ Diamond问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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

因为QQuickPaintedItemQQuickItem

所以我们有以下问题:

           QQuickItem
          /          \
         /            \
QQuickPaintedItem QQuickFramebufferObject
       /                \
   ReactItem        OpenGlBufferItem

我需要的是

           QQuickItem
          /          \
         /            \
QQuickPaintedItem QQuickFramebufferObject
       /                \
   ReactItem            /
       \               /
        \             /
        OpenGlBufferItem

通常,为了解决钻石问题,我们只需声明某些类实际上是从其他类继承而来.但是,我无法声明类RectItemQQuickPaintedItemQQuickFrameBufferObject,因为它们已经给出.

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问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆