Конечно, но не так, как хотелось бы. C ++ не имеет никакого отражения, поэтому вы должны создать механизм самостоятельно: (см. Ниже для EDIT, который реализует карту указателей фабрики)
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Base
{
};
class Dog : public Base
{
};
class Cat : public Base
{
};
int main()
{
typedef vector<string> strings;
strings names;
names.push_back("Dog");
names.push_back("Cat");
names.push_back("Dog");
names.push_back("Cat");
typedef vector<Base*> Bases;
Bases my_objs;
for( strings::const_iterator it = names.begin(), it_end = names.end(); it != it_end; ++it )
{
if( *it == "Dog" )
my_objs.push_back(new Dog);
else if( *it == "Cat" )
my_objs.push_back(new Cat);
}
}
EDIT:
Любое решение, которое вы придумали в C ++, будет в корне некоторой разновидностью вышеупомянутого. Один из распространенных вариантов - попытаться избавиться от блока if
, выполнив поиск. Это может быть реализовано с использованием объекта map
, который связывает имя объекта с функцией, которая его создает. В этом подходе следует отметить, что указатели функций на карте должны иметь одинаковую сигнатуру, то есть фабричные методы Dog
и Cat
должны принимать одинаковое количество и тип параметров. Эта проблема может быть решена с помощью Boost::Any
( ссылка ) или другими героическими методами, но это выходит за рамки этого поста.
Вот решение, которое реализует map
указателей метода фабрики:
#include <string>
#include <vector>
#include <map>
using namespace std;
class Base
{
public:
virtual ~Base() {};
};
class Dog : public Base
{
public:
static Base* make_dog() { return new Dog; }
};
class Cat : public Base
{
public:
static Base* make_cat() { return new Cat; }
};
typedef Base*(*ObjFactoryFn)();
typedef map<string, ObjFactoryFn> Factories;
int main()
{
// set up the map of object factory pointers
Factories factories;
factories["Dog"] = &Dog::make_dog;
factories["Cat"] = &Cat::make_cat;
// build list of objects we want
typedef vector<string> strings;
strings names;
names.push_back("Dog");
names.push_back("Cat");
names.push_back("Dog");
names.push_back("Cat");
// build objects using the factory map
for( strings::const_iterator it = names.begin(), it_end = names.end(); it != it_end; ++it )
{
// construct
Base* my_obj = factories[*it](); // this should use map's "find" method for robustness
// destroy
delete my_obj;
}
}