C++:undefined reference to vtable 原因与解决办法[转]

[转]undefined reference to vtable 原因与解决办法

 

最近在写一套基础类库用于SG解包blob字段统计,在写完了所有程序编译时遇到一个郁闷无比的错误: 
MailBox.o(.text+0x124): In function `CMailBox::CMailBox[not-in-charge](CMmogAnalyseStatManager*)': 
../src/MailBox.cpp:27: undefined reference to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' 
MailBox.o(.text+0x182): In function `CMailBox::CMailBox[in-charge](CMmogAnalyseStatManager*)': 
../src/MailBox.cpp:27: undefined reference to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' 
MailBox.o(.gnu.linkonce.t._ZN8CMailBoxD1Ev+0x33): In function `CMailBox::~CMailBox [in-charge]()': 
../include/MailBox.hpp:22: undefined reference to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' 
MailBox.o(.gnu.linkonce.t._ZN8CMailBoxD1Ev+0x4f):../include/MailBox.hpp:22: undefined reference to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' 
MailBox.o(.gnu.linkonce.t._ZN8CMailBoxD0Ev+0x33): In function `CMailBox::~CMailBox [in-charge deleting]()': 
../include/MailBox.hpp:22: undefined reference to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' 
MailBox.o(.gnu.linkonce.t._ZN8CMailBoxD0Ev+0x4f):../include/MailBox.hpp:22: more undefined references to `CSgAnalyseStatBase::~CSgAnalyseStatBase [not-in-charge]()' follow 
MailBox.o(.gnu.linkonce.r._ZTI8CMailBox+0x8): undefined reference to `typeinfo for CSgAnalyseStatBase' 
SgAnalyseStatBase.o(.text+0x1d): In function `CSgAnalyseStatBase::CSgAnalyseStatBase[not-in-charge](CMmogAnalyseStatManager*)': 
../../sg_analyse_base/src/SgAnalyseStatBase.cpp:22: undefined reference to `vtable for CSgAnalyseStatBase' 
SgAnalyseStatBase.o(.text+0x117): In function `CSgAnalyseStatBase::CSgAnalyseStatBase[in-charge](CMmogAnalyseStatManager*)': 
../../sg_analyse_base/src/SgAnalyseStatBase.cpp:22: undefined reference to `vtable for CSgAnalyseStatBase' 
collect2: ld returned 1 exit status 
make: *** [MailBox] Error 1 
         这个问题困扰了我好几天,上班时间比较多人打扰,周末到了,决心一定要在这个周末将问题解决。搜索“vtable for”时总是搜到Qt出现的undefined reference to `vtable for`,找不到问题所在,一筹莫展。将编译环境从slack ware换到SLES,还是出现同样的错误。仔细看看,所有obj文件都已正常生成,是在链接成bin文件的时候出错的。再从错误信息中找没有搜索过的关键词来搜索,尝试了许多关键词后终于在搜索“undefined reference to `typeinfo”时在http://www.wellho.net/上看到: 
undefined reference to typeinfo - C++ error message 

There are some compiler and loader error messages that shout obviously as to their cause, but there are others that simply don't give the new user much of an indication as to what's really wrong. And most of those I get to know pretty quickly, so that I can whip around a room during a course, making suggestions to delegate to check for missing ; characters or double quotes, to check that they have used the right type of brackets for a list subscript and haven't unintentionally written a function call, etc. 

Here's one of the more obscure messages from the Gnu C++ compiler - or rather from the loader: 

g++ -o polygon shape.o circle.o square.o polygon.o 
circle.o(.gnu.linkonce.r._ZTI6Circle+0x8): undefined reference to `typeinfo for Shape' 
square.o(.gnu.linkonce.r._ZTI6Square+0x8): undefined reference to `typeinfo for Shape' 
polygon.o(.gnu.linkonce.t._ZN5ShapeC2Ev+0x8): In function `Shape::Shape()': 
: undefined reference to `vtable for Shape' 
collect2: ld returned 1 exit status 


And you can be scratching you head for hour over that one! 

The error? shape.o contains a base class from which classes are derived in circle.o and square.o .. but virtual function(s) in shape's definition are missing null bodies. 

The fix? You've got line(s) like 
virtual float getarea() ; 
that should read 
virtual float getarea() {} ; 

The complete (working) source code files for this example are available here 

         按照文中所说稍微修改了一下,在析构函数后面添加了{},再make,成功了,高兴啊!问题终于解决了。我的所有虚函数都是有定义的,没想到就因为写基类的这个虚析构函数大意,没写函数体就出现了一个困扰我几天的莫名其妙的错误。就virtual ~CSgAnalyseStatBase();和virtual ~CSgAnalyseStatBase() {};的区别,编译可以通过却搞出个莫名其妙的链接错误。链接器linker需要将虚函数表vtable 放入某个object file,但是linker无法找到正确的object文件。这个错误常见于刚刚创建一系列有继承关系的class的时候,这个时候很容易忘了给base class的virtual function加上函数实现。解决办法:给基类的virtual函数加上本来就应该有的function body。当含有虚函数的类未将析构函数声明为virtual时也会出现这个链接错误。不管如何,问题解决了,再辛苦也是值得的,以后在写代码时一定要严谨。

posted @ 2014-04-18 15:41  johnny_HITWH  阅读(17248)  评论(0编辑  收藏  举报