2010-07-28 86 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类将能够实例化任何类型的水果在未来增加。