由于您使用继承,因此您需要一个工厂函数来生成任何派生类型...
template<typename T>
base * spawn ()
{
return new T();
}
...和一个支持随机访问的容器operator[]。
如果您需要不连续的索引,请选择地图:
std::map<int, base *(*)()> map_spawner =
{
{ 0, &spawn<child_1> },
{ 1, &spawn<child_2> }
};
如果索引是连续的,则选择一个向量:
std::vector<base *(*)()> vec_spawner =
{
&spawn<child_1>,
&spawn<child_2>
};
工作示例:
#include <map>
#include <vector>
class base
{
public:
virtual ~base () = default;
public:
virtual int f () const = 0;
};
class child_1 : public base
{
public:
int f () const override { return 1; }
};
class child_2 : public base
{
public:
int f () const override { return 2; }
};
template<typename T>
base * spawn ()
{
return new T();
}
int main ()
{
// With a vector
std::vector<base *(*)()> vec_spawner =
{
&spawn<child_1>,
&spawn<child_2>
};
base * child = vec_spawner[0]();
// Do something with child here ...
delete child;
// With a map
std::map<int, base *(*)()> map_spawner =
{
{ 0, &spawn<child_1> },
{ 1, &spawn<child_2> }
};
child = map_spawner[1]();
// Do something with child here ...
delete child;
}
现在您可以使用用户输入来生成特定实例。
如果您的派生类型构造函数不共享相同的参数,不幸的是据我所知您不能使用任何容器......我能想到的唯一接近的可能性是这个(工作示例):
#include <utility>
class base
{
public:
virtual ~base () = default;
public:
virtual int f () const = 0;
};
class child_1 : public base
{
public:
int f () const override { return 1; }
};
class child_2 : public base
{
public:
child_2 (int i) { (void) i; }
public:
int f () const override { return 2; }
};
template<typename... Args>
base * spawn (int input, Args && ... args)
{
switch (input)
{
case 0: return new child_1 {};
case 1: return new child_2 { std::forward<Args>(args)... };
// ...
}
return nullptr;
}
int main ()
{
int input = 1;
base * child = spawn(input, 42);
// Do something with child here ...
delete child;
}