我有一個基類基地它定義了一個虛函數。類派生的現在繼承它並實現/覆蓋該虛函數。下面的代碼工作得很好:虛擬函數+帶基類指針的STL容器
Base* pB = new Derived();
pB->virtual_function(); // function of class Derived gets called -> good
我的問題是,我現在我所有的衍生實例存儲在STL容器std::map<ID, Base*>
。這似乎會導致問題,因爲當我稍後迭代該容器並嘗試每個基地 *調用我的虛函數時,運行時只能將指針識別爲類型基地 *並且不會在類中調用覆蓋的實現派生。
有沒有一種方法可以按預期工作,或者我在這裏錯過了一個關鍵點?
編輯1:請求一些額外的代碼,所以在這裏我們去:
std::map<ComponentType, Base*> m_Components;
// The factory instantiates a Derived* (via functors) and returns it as Base*
Base* pB = m_pComponentFactory->createComponent(this, type);
// Lazy insert (since there is no map entry with key 'type' at that stage)
m_Components[type] = pB;
[...]
Base* pB;
for(ComponentMap::const_iterator it = m_Components.begin(); it != m_Components.end(); ++it)
{
pB = it->second;
pB->virtual_function(); // goes to Base instead of Derived
}
編輯2:有一件事我剛剛意識到的是,我不叫dynamic_cast
(或類似的東西)後通過仿函數創建Derived實例(但我不知道該怎麼投它,因爲它全是通用的/動態的)。這僅僅是一個return creator()
,創造者就是函子。這是問題嗎?
typedef Base*(*ComponentCreator)([some params]);
編輯3:(自時基開始渲染和位置被派生類) 實際函子例如這樣定義:
創建者類型(functon型)的定義
&Renderable::Create<Renderable> // or
&Location::Create<Location>
其中Create()方法是類Base中的模板函數。
template<typename T>
static Component* Create([some params])
{
return new T([some params]);
}
編輯4: 的問題似乎是我的clone()+ CopyConstructor處理。我的克隆目前看起來是這樣的:
Base* Base::clone() const
{
return new Base(*this);
}
因爲我只創建一個基地 *,虛擬分辨率以後不能工作。我現在留下的問題是,我錯過了一個想法,如何改變克隆。如所示編輯1我有我的m_Components
地圖與基地*指針。我現在需要克隆他們,但我只知道他們是基地 *而不是確切的衍生物。想到的一個想法可能是存儲用於創建派生的實例的仿函數,以便稍後重用它。所以我的克隆看起來像這樣:
Base* Component::clone() const
{
return m_pCreationFunctor([some params]);
}
有人看到更好的方法?
你能告訴你如何存儲你的元素在容器中?理論上,你不應該有這個問題。 –
你做錯了什麼。這個想法是正確的,應該工作。你是否意外地在任何地方切片? –
當你將它們存儲在你的容器中時,你必須以某種方式存儲一個指向基類的指針,而不是派生類 – Lieuwe