2010-05-25 59 views
1

我知道關於缺少typeinfo的鏈接器錯誤的標準答案通常還涉及到vtable和一些我忘記實際定義的虛函數。g ++鏈接器錯誤 - typeinfo,但不是vtable

我相當肯定這不是這次的情況。

這裏的錯誤:

UI.o:在功能boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::Resource::GroupByState>(boost::shared_ptr<Graphics::Resource::GroupByState> const&, boost::detail::dynamic_cast_tag)': UI.cpp:(.text._ZN5boost10shared_ptrIN8Graphics7Widgets9WidgetSetEEC1INS1_8Resource12GroupByStateEEERKNS0_IT_EENS_6detail16dynamic_cast_tagE[boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::Resource::GroupByState>(boost::shared_ptr<Graphics::Resource::GroupByState> const&, boost::detail::dynamic_cast_tag)]+0x30): undefined reference to所屬類別的圖形::小工具::視窗元件」

的厭惡重整名稱運行C++ filt的顯示,它實際上是在看.boost :: shared_ptr的:: shared_ptr的(升壓:: shared_ptr的常量&,提振::詳細:: dynamic_cast_tag)

繼承層次結構看起來像

class AbstractGroup 
{ 
    public: 
     virtual ~AbstractGroup(); 
     typedef boost::shared_ptr<AbstractGroup> Ptr; 
     ... 
}; 

class WidgetSet : public AbstractGroup 
{ 
    public: 
     virtual ~WidgetSet(); 
     typedef boost::shared_ptr<WidgetSet> Ptr; 
     ... 
}; 

class GroupByState : public AbstractGroup 
{ 
    public: 
     virtual ~GroupByState(); 
     ... 
}; 

然後是這樣的:

class UI : public GroupByState 
{ 
    public: 
     virtual ~UI(); 
     ... 
     void LoadWidgets(GroupByState::Ptr resource); 
     ... 
}; 

那麼原來的執行:

void UI::LoadWidgets(GroupByState::Ptr resource) 
{ 
    WidgetSet::Ptr tmp(boost::dynamic_pointer_cast<WidgetSet>(resource)); 
    if(tmp) 
    { 
     ... 
    } 
} 

對我而言愚蠢的錯誤(嘗試投放到同級類與共享母體),即使錯誤是怎麼樣神祕的。

更改爲此:

void UI::LoadWidgets(AbstractGroup::Ptr resource) 
{ 
    WidgetSet::Ptr tmp(boost::dynamic_pointer_cast<WidgetSet>(resource)); 
    if(tmp) 
    { 
     ... 
    } 
} 

(這我相當肯定就是我其實是在做)給我留下了非常類似的錯誤:

UI.o:在功能boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::_Drawer::Group>(boost::shared_ptr<Graphics::_Drawer::Group> const&, boost::detail::dynamic_cast_tag)': UI.cpp:(.text._ZN5boost10shared_ptrIN8Graphics7Widgets9WidgetSetEEC1INS1_7_Drawer5GroupEEERKNS0_IT_EENS_6detail16dynamic_cast_tagE[boost::shared_ptr<Graphics::Widgets::WidgetSet>::shared_ptr<Graphics::_Drawer::Group>(boost::shared_ptr<Graphics::_Drawer::Group> const&, boost::detail::dynamic_cast_tag)]+0x30): undefined reference to所屬類別爲圖形::小工具::視窗元件」 collect2:LD返回1個退出狀態

dynamic_cast_tag是升壓/ shared_ptr.hpp只是一個空的結構。這只是一個猜測,推動可能有任何事情來處理這個錯誤。

在WidgetSet :: Ptr中傳遞完全消除了對演員的需求,而且構建得很好(這就是爲什麼我認爲這個問題比標準答案更多的原因)。

顯然,我正在修剪很多可能很重要的細節。我的下一步就是將它縮小到無法構建的最小例子,但我想我會嘗試懶惰的方式,並首先在這裏進行刺探。

TIA!

編輯:顯示一些更多的細節,人們已經評論了

+0

增加@Drew霍爾的答案below.dynamic_cast需要RTTI存儲在vftable但因爲你沒有任何虛方法,它沒有地方存放。 – 2010-05-26 00:49:27

+0

Perharps你應該要求賞金。 – Alerty 2010-06-12 01:41:25

回答

0

會員是否是私人的?如果是這樣,請嘗試在課程成員之前添加protected:

class AbstractGroup 
{ 
protected: 
    typedef boost::shared_ptr<AbstractGroup> Ptr; 
    ... 
}; 


class WidgetSet : public AbstractGroup 
{ 
protected: 
    typedef boost::shared_ptr<WidgetSet> Ptr; 
    ... 
}; 

返回到您的代碼示例後顯示另一件事。它看起來像你試圖使用多態性。唯一的問題是您正在將共享指針對象動態地轉換爲WidgetSet。讀完documentation之後,我相信你應該寫resource.get_pointer()因爲你想在shared_ptr對象中轉換指針而不是shared_ptr對象本身。我並不是很熟悉,所以請告訴我這是否合理!

+0

我原本應該展示的另一個細節:所有這些作品都是公開的。 Boost通過添加dynamic_pointer_cast作爲標準dynamic_cast的包裝來實現一些魔力。你所描述的東西似乎是一個相當常見的錯誤,也可能是他們首先使用魔法的原因。如果你做一個get()時,將dynamic_cast,然後將其分配給另一個shared_ptr的,它會風得到刪除兩次。 – James 2010-05-26 13:51:19

+0

非常真實!我讀得有點太快了。 – Alerty 2010-05-27 02:19:27

1

沒有看到你的整個AbstractGroup類是很難確定的,但它聽起來像你可能不會在你的類層次結構的任何虛擬功能。嘗試在AbstractGroup中定義一個虛擬析構函數(即使是內聯函數也會這樣做),看看它是否有所作爲。沒有一個虛擬函數,就沒有vtable,因此沒有地方掛起typeinfo數據。

+0

對不起,我應該已經證明了這一點。每個班級都有明確的虛擬成員。 – James 2010-05-26 13:45:19