undefinedreferenceto`vtablefor出现原因
来源:互联网 发布:sizing options软件 编辑:程序博客网 时间:2024/05/08 23:38
undefinedreferenceto`vtablefor出现原因
今天考试,大提示在这里列举的问题也是再编写Qt程序时,总是遇到的问题,问题普遍,而答案却不唯一,解释这一个问题的说法很多,往往只适合某一种情况,因为这个错误太笼统了,它就是-- “undefined reference to `vtable for”可能你看着很熟悉,似乎在c++程序中也遇到过这个问题,你说对了,有时候这个错误,不只是qt的原因,还有你的c++程序的原因。
一:
预编译器打开宏Q_OBJECT,声明若干个由moc处理(implement)的成员函数。如果得到类似于“undefined reference to vtable for LcdNumber”的编译错误(if you get compiler errors along the lines of "undefined reference to vtable for LcdNumber"),你可能是忘记了执行moc,或者忘记了将moc输出加入到link命令里。
某一个类中如果加入Q_OBJECT后,则link时提示:undefined reference to vtable for "xxx::xxx".删掉它则没有任何问题.
解决:尝试(1):把所有的obj文件和uic文件删除,重新编译.仍然失败.
去trolltech的mail lists找到原因: 因为qmake生成Makefile的时候,这个类的头文件中并没有Q_OBJECT,所以在相应的Makefile里面并没有用moc xxx.h命令,最终导致链接失败.重新运行qmake,问题解决.
在查找解决方法的时候,附带发现一点:
qmake 不会处理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文件,再包含到.cpp里面去,才能解决这个问题.
这里可以发现问题的出现是因为没有moc生成相应的moc文件,之后连接就出问题。
我找了好多源码之类的问题,就是没有找pro的错误,后来想到qt中moc我们是有make做的
qt的make编译是根据Makefile来的,而Makefile是由pro文件来的。这才想到了找pro文件的错误。
from: http://www.cublog.cn/u/16292/showart_136087.html
二:
undefined reference to vtable for "xxx::xxx"
原 因:qmake不会处理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文件,再包含到.cpp里面去,才能解决这个问题.
其他:
1.问题: QGLViewer中的函数不能正常link.
解决: 翻看其源代码,发现是因为从源码安装libQGLViewer时,编译用了Qt 3,而我的程序中用Qt4 编译.所以必须重新用Qt4编译.但是,更改QTDIR 环境变量为Qt4后,重新编译的话,qmake生成makefile时就提示出错.进一步发现,是因为虽然设了QTDIR为Qt4,头文件和库文件都会使 用Qt4,但是moc,uic等都是用的qt3版的,再把PATH环境变量改动后,一切ok.
2.问题:某一个类中如果加入Q_OBJECT后, 则link时提示:undefined reference to vtable for "xxx::xxx".删掉它则没有任何问题.
解决:尝试(1):把所有的obj文件和uic文件删除,重新编译.仍然失败.去trolltech的 mail lists找到原因: 因为qmake生成Makefile的时候,这个类的头文件中并没有Q_OBJECT,所以在相应的Makefile里面并没有用moc xxx.h命令,最终导致链接失败.重新运行qmake,问题解决.在查找解决方法的时候,附带发现一点:
qmake 不会处理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文件,再包含到.cpp里面去,才能解决这个问题.
3. 看Qt的reference发现: 可以connect(pObjA, SIGNAL(someSignalA()),pObjB,SIGNAL(someSignalB()));这样pObjA发出的someSingalA 会导致pObjB发出someSignalB,从而形成信号接力.
from:http://blog.donews.com/netexe/archive/2006/02/09/720544.aspx
三:
编译报错的部分是:
CODE:[Copy to clipboard]tmp\obj\release_shared\myplot.o(.text+0x194):myplot.cpp: undefined reference to
`vtable for MyPlot’
tmp\obj\release_shared\myplot.o(.text+0x19b):myplot.cpp: undefined reference to
`vtable for MyPlot’
tmp\obj\release_shared\myplot.o(.text+0x934):myplot.cpp: undefined reference to
`vtable for MyPlot’
tmp\obj\release_shared\myplot.o(.text+0x93b):myplot.cpp: undefined reference to
`vtable for MyPlot’
collect2: ld returned 1 exit status
你 MyPlot 是不是声明了什么 virtual 的 方法, 但在实现(cpp)文件里没有实现。
看了一下, 现在推测一下。 MyPlot 继承了 QwtPlot, 现在报的这个错, 应该是这个意思,
1. QwtPlot 里含有 vritual 方法, 所以你的继承类需要一个 virtual 的析构函数
2. QwtPlot 里含有 纯虚的方法, 你没有继承, 而这个可能性比较小
所以, 你可以:
在MyPlot里声明一下一个虚的析构函数
virtual ~MyPlot() {} 来源:233网校-计算机二级考试
我们来看一个简单些的例子吧:
CODE:[Copy to clipboard]#include <qapplication.h>
#include <qpushbutton.h>
class myWidget :public QWidget
{
Q_OBJECT
public:
myWidget(QWidget *parent = 0);
public slots:
void shutDown();
private:
QPushButton *exit;
};
myWidget::myWidget(QWidget *parent):QWidget(parent)
{
setMinimumSize(120, 180);
setMaximumSize(120, 180);
exit = new QPushButton("ShutDown!",this);
connect(exit,SIGNAL(clicked()),this,SLOT(shutDown()));
}
void myWidget::shutDown()
{
system("halt");
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
myWidget *w = new myWidget();
w->show();
app.exec();
}
还是报错:
CODE:[Copy to clipboard]shut.o(.text+0x21): In function `myWidget::myWidget[not-in-charge](QWidget*, char const*)’:
: undefined reference to `vtable for myWidget’
shut.o(.text+0x28): In function `myWidget::myWidget[not-in-charge](QWidget*, char const*)’:
: undefined reference to `vtable for myWidget’
shut.o(.text+0x141): In function `myWidget::myWidget[in-charge](QWidget*, char const*)’:
: undefined reference to `vtable for myWidget’
shut.o(.text+0x148): In function `myWidget::myWidget[in-charge](QWidget*, char const*)’:
: undefined reference to `vtable for myWidget’
collect2: ld returned 1 exit status
这是我从l搜索引擎上搜到的例子,从代码中好像看不到明显的错误吧
我自己试了一下编译也是出错
刚才那个简单的例子的原因可能是这样的:
QUOTE:
2.问题:某一个类中如果加入Q_OBJECT后,则link时提示:undefined reference to vtable for "xxx::xxx".删掉它则没有任何问题.
解决:尝试(1):把所有的obj文件和uic文件删除,重新编译.仍然失败.
去trolltech的mail lists找到原因: 因为qmake生成Makefile的时候,这个类的头文件中并没有Q_OBJECT,所以在相应的Makefile里面并没有用moc xxx.h命令,最终导致链接失败.重新运行qmake,问题解决.
在查找解决方法的时候,附带发现一点:
qmake不会处理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文件,再包含到.cpp里面去,才能解决这个问题.
知道你的问题了, 上面的例子不好, 因为你这个把main和类放在一起了。 如果分开, 可能就没问题, 包括 h和 cpp 分开。
要解决上面的问题, 在你main.cpp 最后加一行
#include "main.moc"
然后把除了 main.cpp 的其它文件都删了。重新来, 没问题的。
所以, 我估计你前面提到的问题也是没有链接 moc 文件。 你在你的 myplot.cpp 文件最后加一行: #include "myplot.moc" 试试看。
另外: 你main 没有返回值, 编译会警告, 而且程序最后一行不是只含有回车, 也会警告。来源:233网校-计算机二级考试
Setting up a Qt environment...
-- QTDIR set to E:\Qt\4.8.4
-- Added E:\Qt\4.8.4\bin to PATH
-- QMAKESPEC set to "win32-msvc2010"
Setting environment for using Microsoft Visual Studio 2010 x86 tools.
E:\Qt\4.8.4>d:
D:\>cd "D:\My Documents\Visual Studio 2010\Projects\helloworld\helloworld"
D:\My Documents\Visual Studio 2010\Projects\helloworld\helloworld>moc main.cpp>m
oc_main.h
D:\My Documents\Visual Studio 2010\Projects\helloworld\helloworld>
#include <QtCore/QCoreApplication>#include <QDebug> #include <qobject> #include <QtGui/QWidget>//h把QWidget头文件包含进来;信号槽要包含QObject/*一个小的Qt类如下: class Foo : public QObject { Q_OBJECT public: Foo(); int value() const { return val; } public slots: void setValue( int ); signals: void valueChanged( int ); private: int val; };这个类有同样的内部状态,和公有方法来访问状态,但是另外它也支持使用信号 和槽的组件编程:这个类可以通过发射一个信号,valueChanged(),来告 诉外面的世界它的状态发生了变化,并且它有一个槽,其它对象可以发送信号给这个 槽。所有包含信号和/或者槽的类必须在它们的声明中提到Q_OBJECT。槽可以由应用程序的编写者来实现。这里是Foo::setValue()的一个可能的实现: void Foo::setValue( int v ) { if ( v != val ) { val = v; emit valueChanged(v); } }emit valueChanged(v)这一行从对象中发射valueChanged信 号。正如你所能看到的,你通过使用emit signal(arguments)来发射信号。下面是把两个对象连接在一起的一种方法: Foo a, b; connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); b.setValue( 11 ); // a == undefined b == 11 a.setValue( 79 ); // a == 79 b == 79 b.value(); 调用a.setValue(79)会使a发射一个valueChanged() 信号,b将会在它的setValue()槽中接收这个信号,也就是b.setValue(79) 被调用。接下来b会发射同样的valueChanged()信号,但是因为 没有槽被连接到b的valueChanged()信号,所以没有发生任何事 (信号消失了)。注意只有当v != val的时候setValue()函数才会设置这个值 并且发射信号。这样就避免了在循环连接的情况下(比如b.valueChanged() 和a.setValue()连接在一起)出现无休止的循环的情况。这个例子说明了对象之间可以在互相不知道的情况下一起工作,只要在最初的时在 它们中间建立连接。*/ class Foo : public QObject { Q_OBJECT public:Foo(){val=0;}~Foo(){} int value() const { return val; } public slots: void setValue( int ); signals: void valueChanged( int ); private: int val; }; void Foo::setValue( int v ) { if ( v != val ) { val = v; emit valueChanged(v); } }#include "moc_main.h"int main(int argc, char *argv[]){QCoreApplication app(argc, argv);Foo a, b; QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); b.setValue( 11 ); // a == undefined b == 11qDebug()<<"a ="<<a.value()<<" ; b ="<<b.value()<<endl; a.setValue( 79 ); // a == 79 b == 79 qDebug()<<"a ="<<a.value()<<" ; b ="<<b.value()<<endl; qDebug()<<"Hello Word";return app.exec();}/*a = 0 ; b = 11a = 79 ; b = 79Hello Word*/
- undefinedreferenceto`vtablefor出现原因
- undefinedreferenceto`vtablefor出现原因
- undefinedreferenceto`vtablefor出现原因我这里的一个答案
- undefinedreferenceto`vtablefor问题总结
- undefined reference to `vtablefor出现原因
- 出现此错误,原因
- 编辑器出现乱码原因
- DW20.exe出现原因
- LazyInitializationException出现原因
- java uncaughtException出现原因
- Illegal instruction 出现原因
- 出现乱码的原因
- java出现的原因
- 出现xxxViewController respondsToSelector 原因
- AsyncTask出现RejectExcetionExcetion原因
- Android ANR出现原因
- springmvc的出现原因
- Eclipse出现FileInputStream出现例外原因分析
- 【部门经理亲授】关于LOG的相关注意事项,备忘!
- .NET实现Repeater控件+AspNetPager控件分页
- 新浪微博开发No1 access token 获取
- Erlang orddict
- matrix
- undefinedreferenceto`vtablefor出现原因
- 苹果消息推送服务教程(下有php服务端DEMO,已验证可用)
- Bubble(8)
- linux+postfix+openwebmail+sasl搭建邮件服务器
- Vim的操作技巧节选
- 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
- 自定义button
- openssl 1.0.0编译
- Linux系统邮件服务器的搭建过程解析