C ++中的动态实例化

时间:2010-07-28 22:25:15

标签: c++ polymorphism

我希望我的代码是可扩展的,在运行时我创建对象。

例如,假设我有一个Grocery类,它有一系列水果,我想用水果中的对象填充这个水果数组。

class Fruit{

};

class Grocery{

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

class Apple: Fruit{

};

class Pineapple: Fruit{

};

现在在运行时我希望我的Grocery类向量m_fruits用Apple和Pineapple的类对象填充。所以它有可能在某种程度上。

如果我将来添加另一个水果作为草莓,它的对象将被创建并动态添加到Grocery的向量中,而不会改变Grocery类的实现吗?

代码帮助将不胜感激。

4 个答案:

答案 0 :(得分:4)

检查你的教科书。它可能提到您只能将指针处理为多态的类型。换句话说,指针向量的向量可以将指针带到苹果或菠萝。

答案 1 :(得分:2)

好吧,如果你想这样做,你的Grocery类可以生成任何类型的水果。即使是在杂货课程被锁定之后实施的水果,我想你可能会追随以下内容?

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课程将能够实例化将来添加的任何类型的水果。

答案 2 :(得分:0)

假设Fruit具有纯虚函数(由virtual func() = 0表示),您需要在向量std::vector<Fruit*>内存储指向Fruit对象的指针。

不幸的是,标准容器并不擅长处理指针,你必须在Grocery的析构函数中删除向量中的所有对象。您可以考虑TR1或升级库中的shared_ptr

关于命名的一个词:Instantiation在这种情况下不是正确的词。

答案 3 :(得分:0)

在基础类型的任何容器中,如果没有对象切片,则无法按值存储派生类型的对象。

您需要执行以下操作之一:

  1. 使用基本类型的原始指针向量,例如: std::vector<Fruit*>并自行管理各个Fruit实例的生命周期(这是最不可取的选项)。
  2. 使用指向基本类型的智能指针向量,例如: std::vector<boost::shared_ptr<Fruit> >,并允许引用计数来管理各个项目的生命周期。
  3. 使用boost::ptr_vector<Fruit>存储商品,商品的生命周期与包含ptr_vector的商品的生命周期绑定。
  4. 根据您的需要,#2&amp; #3是优选的。应避免使用#1,因为它涉及手动管理生命周期,如果操作不正确,很容易导致内存泄漏。