我希望我的代码是可扩展的,在运行时我创建对象。
例如,假设我有一个Grocery类,它有一系列水果,我想用水果中的对象填充这个水果数组。
class Fruit{
};
class Grocery{
std::vector<Fruit*> m_fruits;
};
class Apple: Fruit{
};
class Pineapple: Fruit{
};
现在在运行时我希望我的Grocery类向量m_fruits
用Apple和Pineapple的类对象填充。所以它有可能在某种程度上。
如果我将来添加另一个水果作为草莓,它的对象将被创建并动态添加到Grocery的向量中,而不会改变Grocery类的实现吗?
代码帮助将不胜感激。
答案 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)
在基础类型的任何容器中,如果没有对象切片,则无法按值存储派生类型的对象。
您需要执行以下操作之一:
std::vector<Fruit*>
并自行管理各个Fruit
实例的生命周期(这是最不可取的选项)。std::vector<boost::shared_ptr<Fruit> >
,并允许引用计数来管理各个项目的生命周期。boost::ptr_vector<Fruit>
存储商品,商品的生命周期与包含ptr_vector
的商品的生命周期绑定。根据您的需要,#2&amp; #3是优选的。应避免使用#1,因为它涉及手动管理生命周期,如果操作不正确,很容易导致内存泄漏。