如何知道一个类是否继承了其他抽象类?

时间:2018-01-22 09:06:42

标签: c++ qt

我有一个继承Draggable的抽象QWidget类。其他两个类继承Draggable

             QWidget
                |
            Draggable (abstract)
              /   \
             /     \
          Class1  Class2

在主窗口中,在鼠标按下事件中,我想知道被点击的孩子是Draggable

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    QWidget *childWid = childAt(event->pos());
    if (!childWid)
        return;

    // if Draggable is not abstract I can do as below
    /*
    Dragable *obj = new Dragable;
    if (!childWid->metaObject()->inherits(obj->metaObject()))
        return;
    */
}

我可以通过将childWid->metaObject()->className()Class1Class2进行比较来检查,但Draggable有很多孩子。所以我想知道如何确定孩子是否继承Draggable

3 个答案:

答案 0 :(得分:6)

另一种方法是使用qobject_cast函数,该函数类似于dynamic_cast,但仅适用于QObjects。使用qobject_cast vs dynamic_cast的好处是前者即使禁用RTTI也能正常工作。

前提是你的Draggable类应该直接或间接地继承QObject,它实际上是这样做的,并用Q_OBJECT宏声明。即。

class Draggable : public QWidget
{
    Q_OBJECT
[..]
};

并在您的示例中:

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    QWidget *childWid = childAt(event->pos());
    if (!childWid)
        return;

    // if Draggable is not abstract I can do as below
    if (!qobject_cast<Draggable *>(childWid))
    {
        // Not a Draggable
        return;
    }
}

答案 1 :(得分:3)

您可以使用dynamic_cast

if (auto *draggable = dynamic_cast<Draggable*>(childWid)) {
    do_stuff()
}

答案 2 :(得分:2)

没有理由实例化Dragable。它有一个可以使用的类元对象:staticMetaObject

因此,尽管qobject_cast是首选解决方案,但对代码的最直接修复方法是:

void MainWindow::mousePressEvent(QMouseEvent *event) {
    auto *child = childAt(event->pos());
    if (!child)
        return;
    if (!child->metaObject()->inherits(&Draggable::staticMetaObject))
        return;
    auto *draggable = static_cast<Draggable*>(child);
    qDebug() << draggable;
}

qobject_cast变体会更简洁:

void MainWindow::mousePressEvent(QMouseEvent *event) {
    auto *draggable = qobject_cast<Draggable*>(childAt(event->pos()));
    if (!draggable)
        return;
    qDebug() << draggable;
}