[英]Dynamic instantiation in C++
我希望代码可以扩展,以便在运行时创建对象。
例如,假设我有一个Grocery类,其中包含一组水果,并且我想用从水果派生的对象填充此水果数组。
class Fruit{
};
class Grocery{
std::vector<Fruit*> m_fruits;
};
class Apple: Fruit{
};
class Pineapple: Fruit{
};
现在在运行时,我希望我的Grocery类向量m_fruits
充满Apple和Pineapple的类对象。 因此有可能以某种方式。
如果将来再添加另一个水果作为草莓,是否会动态创建其对象并将其添加到Grocery的向量中,而无需更改Grocery类的实现?
代码帮助将不胜感激。
检查您的教科书。 它可能提到您只能将指针指向多态类型。 换句话说, 指向水果的指针的矢量可以指向苹果或菠萝的指针 。
好吧,如果您想要这样做,那么您的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
类就可以实例化将来添加的任何类型的水果。
假设Fruit
具有纯虚函数(由virtual func() = 0
),则需要在向量std::vector<Fruit*>
内部存储指向Fruit对象的指针。
不幸的是,标准容器在处理指针方面并不是特别擅长,您将不得不在Grocery
的析构函数中删除向量中的所有对象。 您可能考虑使用TR1或boost库中的shared_ptr
。
关于命名的一个词:在这种情况下, Instantiation
不是正确的词。
您不能在没有对象切片的情况下将按值派生类型的对象存储在任何基本类型的容器中。
您需要执行以下操作之一:
std::vector<Fruit*>
并自己管理各个Fruit
实例的生存期(这是最不希望的选择)。 std::vector<boost::shared_ptr<Fruit> >
,并允许引用计数来管理各个项目的生命周期。 boost::ptr_vector<Fruit>
来存储项目,并且项目的生存期与包含的ptr_vector
的生存期绑定。 根据您的需要,#2&#3是更可取的。 应避免使用#1,因为它涉及手动管理生命周期,并且如果操作不当,很容易导致内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.