C++: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*)': 
http://www.cnblogs.com/sg_analyse_base/src/SgAnalyseStatBase.cpp:22: undefined reference to `vtable for CSgAnalyseStatBase' 
SgAnalyseStatBase.o(.text+0x117): In function `CSgAnalyseStatBase::CSgAnalyseStatBase[in-charge](CMmogAnalyseStatManager*)': 
http://www.cnblogs.com/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時也會出現這個鏈接錯誤。不管如何,問題解決了,再辛苦也是值得的,以後在寫代碼時一定要嚴 謹。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章