假设我有一个成员函数,它创建一个新对象并将其放入类中的数据结构(在本例中为map):
Class A
{
std::map<std::pair<int,int>, BaseClass*> store;
//...
public:
void createObject(?a?)
{
BaseClass* temp = new ?a?;
//place in map...
};
};
其中?a?
是一个参数,可用于创建一个对象,该对象可以是从BaseClass
派生的许多不同类。我能想到这样做的唯一方法是将?a?
设为int
,然后在switch语句中手动输入每种类型。
答案 0 :(得分:3)
使用会员功能模板。在您的示例的上下文中:
template<class T>
void createObject()
{
BaseClass* temp = new T();
//place in map...
};
调用:
a.createObject<B>();
其中a
是A
的实例,而B
是从BaseClass
派生的类型。
答案 1 :(得分:2)
模板是比枚举更好的解决方案,因为它不需要任何维护。将自动支持任何新的子类。指针类型之间的类型安全性保证T是temp的子类(否则赋值将失败)。
Class A
{
std::map<std::pair<int,int>, BaseClass*> store;
//...
public:
template <typename T>
void createObject()
{
BaseClass* temp = new T();
//place in map...
};
};
编译器无法在没有依赖参数的情况下自动推导出模板类型,因此您需要对其进行限定。
Class Foo : public BaseClass { ... };
A a;
a.createObject<Foo>();
答案 2 :(得分:0)
取决于您如何知道要创建的对象类型。
如果将它基于int(例如某个函数的返回代码)是合理的,那么switch语句就可以了。请注意,您需要通过调用new来创建每个对象的类型,然后将对象指针强制转换为BaseClass以放入地图。
如果您传入的是该类型的对象,请使用模板。编辑:作为Jon的回答
答案 3 :(得分:0)
您应该枚举可以创建的可能类,并将其传递给createObject函数,例如:
enum FRUIT_CLASS { APPLE, ORANGE, BANANA };
...
void A::createObject( FRUIT_CLASS )
{
switch(FRUIT_CLASS)
// etc
}
这样,您实际上是将一个整数作为参数传递,但您的代码更易于理解,可修改和维护。