#include <cstdlib>
#include <ctime>
#include <iostream>
#include <map>
#include <vector>
#include <memory>
using namespace std;
// interface
class Base
{
public:
virtual ~Base() { }
virtual int getClassId() = 0;
};
// class A relizes interface Base, has ID == 1 (is used in automatic registration to factory)
class A : public Base
{
public:
const static int ID = 1;
static Base* CreateInstance()
{
return new A();
}
virtual int getClassId()
{
return ID;
}
virtual ~A() { }
};
// class B relizes interface Base, has ID == 2 (is used in automatic registration to factory)
class B : public Base
{
public:
const static int ID = 2;
static Base* CreateInstance()
{
return new B();
}
virtual int getClassId()
{
return ID;
}
virtual ~B() { }
};
// this is the objects factory, with registration only (unregister s not allowed)
class ObjectFactory
{
ObjectFactory() { }
ObjectFactory(ObjectFactory&) { }
public:
virtual ~ObjectFactory() { }
static ObjectFactory& instance()
{
static ObjectFactory objectFactory;
return objectFactory;
}
typedef Base* (*Creator)();
void registerCreator(int id, Creator creator)
{
registry[id] = creator;
}
Base* CreateById(int id)
{
return registry[id]();
}
private:
map<int, Creator> registry;
};
// this template class is used for automatic registration of object's creators
template <class T>
struct RegisterToFactory
{
RegisterToFactory(ObjectFactory& factory)
{
factory.registerCreator(T::ID, &T::CreateInstance);
}
};
namespace
{
// automaticaly register creators for each class
RegisterToFactory<A> autoregisterACreator(ObjectFactory::instance());
RegisterToFactory<B> autoregisterBCreator(ObjectFactory::instance());
}
// lets this this solution
int main(int argc, char *argv[])
{
vector<int> ids;
ids.push_back(static_cast<int>(A::ID));
ids.push_back(static_cast<int>(B::ID));
srand(time(0));
for (int i = 0; i < 20; ++i)
{
int randomClasssId = ids[rand() % ids.size()];
auto_ptr<Base> testObject(ObjectFactory::instance().CreateById(randomClasssId));
cout << "Object of classId = " << testObject->getClassId() << " has been produced by factory." << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
あなたがそのような意味: 'ベクトル V;' –
はあなたがタイプ自身の配列をしたいですか?または、型のオブジェクトの配列? –
@BenjaminLindley:明らかに彼はタイプの配列を望んでいます。しかし、配列項目の型として 'Base'を使用すると誤解を招きます。 –