Q_OBJECT抛出'未定义的引用vtable'错误

时间:2011-01-23 14:24:53

标签: c++ qt linker-errors vtable

我在Windows 7 Ultimate 32位上使用Qt Creator 2.0.1和Qt 4.7.0(32位)。

考虑以下代码,这是产生错误的最小代码:

class T : public QObject, public QGraphicsItem
{
    Q_OBJECT

public:
    T() {}

    QRectF      boundingRect() const {return QRectF();}
    void        paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                      QWidget *widget) {}
};

int main()
{
    T t;
    return 0;
}

上面的代码片段导致以下链接器错误:

  

在函数`T'中:

     

未定义引用'vtable for T'

     

未定义引用'vtable for T'

     

在函数`~T'中:

     

未定义引用'vtable for T'

     

未定义引用'vtable for T'

如果我注释掉包含Q_OBJECT的行,则编译正常。我需要QGraphicsItem的信号和广告位,所以我需要Q_OBJECT

代码有什么问题?感谢。

5 个答案:

答案 0 :(得分:115)

这是因为MOC生成的单元不包含在链接过程中。或者它可能根本没有生成。我要做的第一件事就是将类声明放在一个单独的头文件中,也许构建系统不会扫描实现文件。

另一种可能性是,有问题的类曾经不属于Qt元对象系统(也就是说,它根本没有Q_OBJECT或者根本没有从QObject继承),所以需要再次按顺序运行qmake为MOC创建必要的规则。强制运行qmake的最简单方法是对项目文件进行一些无关紧要的更改以更新其时间戳,例如添加然后删除一些空白区域。或者,如果你正在使用Qt Creator,那么只需从项目上下文菜单中选择“Run qmake”。

答案 1 :(得分:21)

如果要在源文件中定义QObject子类,则需要添加行

#include "file.moc"

在您的类定义之后的某个时刻,源文件的名称是file.cpp。当然,您需要重新运行qmake,以便将运行moc的相应规则添加到Makefile中。

只有在头文件中,类定义中存在Q_OBJECT才会调用moc。如果它是源文件,则需要此额外行来强制使用moc

我确信以前曾问过类似的问题,但我找不到它。

答案 2 :(得分:7)

将Q_OBJECT类放在单独的文件中。这是每个班级的一个.h和一个.cpp。 Qt的元对象宏在这方面有点挑剔。

此外,您可以使用QGraphicsObject来达到目的。在那里节省一些时间。

编辑:我看到你正在使用Creator。在New File或Project中使用其New C ++ Class函数以“正确的方式”创建文件:)

答案 3 :(得分:5)

以下是添加了其他问题中提供的所有修补程序的工作代码(尝试干净编译和这些修复帮助):

#include <QGraphicsItem>

class T : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem) //Required.

public:
    T() {}
    QRectF      boundingRect() const {return QRectF();}
    void        paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                      QWidget *widget) {}
};

int main(int argc, char *argv[])
{
    T *t = new T;
    return 0;
}

#include "main.moc" // Required.

对Troubadour和serge_gubenko的实际信用

答案 4 :(得分:3)

有几件事要看:

  1. 在您的专业档案中添加QT + = gui
  2. 确保仅在头文件中定义QObject派生类(编辑:如Troubadour所说,这不是必需的)
  3. 将Q_INTERFACES(QGraphicsItem)添加到T类的声明中
  4. 下面是一个例子:

    t.h:

    class T : public QObject, public QGraphicsItem
    {
        Q_OBJECT
        Q_INTERFACES(QGraphicsItem)
    
    public:
        T();
        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    };
    

    t.cpp:

    T::T() {}
    
    QRectF T::boundingRect() const
    {
        return QRectF();
    }
    
    void T::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(painter);
        Q_UNUSED(option);
        Q_UNUSED(widget);
    }
    

    我已经尝试编译上面的代码并且没有遇到任何问题。

    希望这有帮助,尊重