¿Alguien sabe de una forma de hacer que las clases derivadas instancian automáticamente una variable estática con un tipo de plantilla (esto no requiere nada del escritor de la clase derivada, o lo fuerza a llamarlo estático? método para hacer válida la definición de clase derivada).Invocación estática automática de tipos derivados
Esto es probablemente imposible de entender, intentaré definirlo mejor.
Básicamente tengo una clase de fábrica global con una función de plantilla llamada registerType. Para cada clase derivada de Entity, necesito que esta función sea llamada con el parámetro template del tipo derivado. Por el momento, tengo que hacerlo manualmente en alguna función init, lo que resulta en un gran bloque de llamadas a esta función, lo que va en contra del principio de las plantillas para mí.
Así que tengo esto:
class Factory
{
template <typename EntityType>
registerEntityType();
};
void someInitFunction()
{
/// All of these are derived from Entity
gFactory.registerEntityType<EntityType1>();
gFactory.registerEntityType<EntityType2>();
gFactory.registerEntityType<EntityType3>();
/// and so on
}
mientras que yo preferiría tener esto:
class Factory
{
template <typename EntityType>
registerEntityType();
};
class Entity // Abstract
{
/// This function should be called automatically with the derived
/// type as a parameter
SomeStaticConstructor<MDerivedType>()
{
gFactory.registerEntityType<MDerivedType>();
}
};
EDIT: Este es el código de la plantilla estática recurrentes que no está funcionando:
Este es mi clase base, y la clase para registrar automáticamente cosas
template <typename DerivedType>
class Registrar
{
public:
Registrar();
void check();
};
template <typename Product, typename DerivedType>
class AbstractFactory: public AbstractFactoryBase<Product>
{
public:
AbstractFactory();
~AbstractFactory();
private:
static Registrar<DerivedType> registrar;
};
constructor
template <typename DerivedType>
Registrar<DerivedType>::Registrar()
{
std::cout << DerivedType::name() << " initialisation" << std::endl;
g_AbstractFactories.registerFactoryType<DerivedType>(DerivedType::name());
}
del registrador y un tipo derivado
class CrateFactory : public AbstractFactory<Entity, CrateFactory>
{
public:
CrateFactory(FactoryLoader* loader);
virtual ~CrateFactory();
Entity* useFactory(FactoryParameters* parameters);
static std::string name()
{
return "CrateFactory";
}
El primer camino Me hollé está haciendo 'Entity' una clase de plantilla, por lo que sabe el tipo derivado . El problema allí es que los tipos derivados tendrían que ser ellos mismos plantillas (y, por lo tanto, ser abstractos), o nunca utilizados como clases base. También he visto macros utilizadas para esto en las bibliotecas de contenedor Win32. Y esta pregunta está relacionada de alguna manera: http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c –
Nm, parece que se llama CRTP, y las respuestas captaron lo que era getting at :) –