提问人:Donotalo 提问时间:1/23/2011 更新时间:11/25/2016 访问量:69105
Q_OBJECT抛出“对 vtable 的未定义引用”错误 [重复]
Q_OBJECT throwing 'undefined reference to vtable' error [duplicate]
问:
我在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
代码有什么问题?谢谢。
答:
这是因为 MOC 生成的单元不包括在链接过程中。或者它可能根本没有生成。我要做的第一件事是将类声明放在单独的头文件中,也许构建系统没有扫描实现文件。
另一种可能性是,有问题的类曾经不属于Qt元对象系统(也就是说,它没有Q_OBJECT,或者可能根本没有继承自QObject),因此需要再次运行qmake才能为MOC创建必要的规则。强制运行 qmake 的最简单方法是对项目文件进行一些无关紧要的更改以更新其时间戳,例如添加然后删除一些空格。或者,如果您使用的是Qt Creator,则只需从项目上下文菜单中选择“运行qmake”。
评论
moc
将Q_OBJECT类放在单独的文件中。即每个类一个 .h 和一个.cpp。Qt的元对象宏在这方面有点挑剔。
此外,您可以将QGraphicsObject用于您的目的。为您节省一些时间。
编辑:我看到您正在使用Creator。在“新建文件”或“项目”中使用其“新建C++类”功能以“正确的方式”创建文件:)
评论
有几件事需要注意:
- 在专业文件中添加 QT += gui
- 确保仅在头文件中定义 QObject 派生类(编辑:正如 Troubadour 所指出的,这不是必需的)
- 将 Q_INTERFACES(QGraphicsItem) 添加到 T 类的声明中
下面是一个示例:
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);
}
我尝试编译上面的代码,但没有问题。
希望这有帮助,问候
评论
如果要在源文件中定义子类,则需要添加以下行QObject
#include "file.moc"
在类定义之后的某个时间点,源文件的名称为 File.cpp。当然,您需要重新运行,以便将要运行的相应规则添加到 Makefile 中。qmake
moc
只有在头文件中,类定义中是否存在 才会被调用。如果它是源文件,则需要强制使用此额外的行。Q_OBJECT
moc
moc
我敢肯定以前有人问过类似的问题,但我找不到。
评论
以下是添加了其他问题中提供的所有修复程序的工作代码(尝试了干净编译,这些修复程序有所帮助):
#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.
所以实际归功于吟游诗人和serge_gubenko
评论