2010-07-28 95 views
2

我希望我的代碼是可擴展的,在運行時創建對象。C++中的動態實例

例如,假設我有一個有水果數組的Grocery類,我想用水果派生的對象填充這個水果數組。

class Fruit{ 

}; 

class Grocery{ 

    std::vector<Fruit*> m_fruits; 
}; 

class Apple: Fruit{ 

}; 

class Pineapple: Fruit{ 

}; 

現在在運行時我希望我的日用雜貨類矢量m_fruits來填充與蘋果和菠蘿的類對象。所以有可能以某種方式。

如果我將來添加另一種水果作爲草莓,它的對象將被創建並動態添加到Grocery矢量中,而不會改變Grocery類的實現?

代碼幫助將不勝感激。

+1

這是功課嗎? – 2010-07-28 22:27:11

+18

使用指針,或者你會得到切片水果...(谷歌「C++切片」) – smerlin 2010-07-28 22:29:57

+1

@smerlin:我可以downvote你的評論壞的雙關嗎? =] ...或者至少從網站修剪它? – Sniggerfardimungus 2010-07-28 22:31:51

回答

4

檢查您的教科書。它可能提到你只能對指針進行多態類型的處理。換句話說,向果實指針向量的向量可以將指針指向蘋果或菠蘿。

+0

UM,還有參考文獻(儘管它們不適用於這種情況)。 – sbi 2010-07-29 07:50:37

0

假設Fruit具有純虛函數(用virtual func() = 0表示),您需要將指針存儲在向量std::vector<Fruit*>內的水果對象。

不幸的是,標準容器並不擅長處理指針,你將不得不刪除你的向量中的所有對象在你的Grocery的析構函數中。您可能會考慮來自TR1或增強庫的shared_ptr

有關命名的一句話:Instantiation在這種情況下不是合適的詞。

0

無法通過值將任何派生類型的對象存儲在基本類型的任何容器中,而不會發生對象切片。

你需要做以下之一:

  1. 使用原始指針的向量爲基本類型,例如std::vector<Fruit*>並自行管理個體的生命週期(這是最不理想的選擇)。
  2. 使用智能指針的矢量指向基本類型,例如,並允許引用計數來管理單個項目的生命週期。
  3. 使用boost::ptr_vector<Fruit>來存儲項目,並且項目的生存期限於包含ptr_vector的項目。

根據您的需要,#2 &#3是優選的。 #1應該避免,因爲它涉及人工努力來管理生命週期,如果做得不正確,很容易導致內存泄漏。

2

那麼,如果你想使它成爲你的食品類可以產生任何類型的水果。即使在食品雜貨課程被鎖定之後已經實施的水果,我想你可能會採取類似以下的措施?

typedef Fruit*(*FruitInstantiatorPtr)(); 

template<class T> 
Fruit* FruitInstantiator() 
{ 
    return new T(); 
} 


// Then in Grocery have a function like: 

static void AddFruitGenerator(FruitInstantiatorPtr instantiatorFunc, string fruitTypeName); 

//// 
//Then someone somewhere can go: 

class MyNewFruit:Fruit{}; 

MyGrocery.AddFruitGenerator(FruitInstantiator<MyNewFruit>, "myAwesomeNewFruit"); 

而且這樣你的Grocery類將能夠實例化任何類型的水果在未來增加。