I am trying to register a bunch of classes with factory at boot time. My strategy is to use static initialization to make sure that the main () factory is ready to go before starting. This strategy seems to work when I link my library dynamically, but not when I link statically; when I bind statically, only some of my static data members are initialized.
Say my factory builds cars. I have CarCreator classes that can create multiple machines, but not all. I want the factory to collect all these CarCreator classes so that the code looking for a new car can go to the factory without knowing who will make the actual construction.
So, I have a
CarTypes.hpp
enum CarTypes
{
prius = 0,
miata,
hooptie,
n_car_types
};
MyFactory.hpp
class CarCreator
{
public:
virtual Car * create_a_car( CarType ) = 0;
virtual std::list< CarTypes > list_cars_I_create() = 0;
};
class MyFactory // makes cars
{
public:
Car * create_car( CarType type );
void factory_register( CarCreator * )
static MyFactory * get_instance();
private:
MyFactory();
std::vector< CarCreator * > car_creator_map;
};
MyFactory.cpp
MyFactory:: MyFactory() : car_creator_map( n_car_types );
MyFactory * MyFactory::get_instance() {
static MyFactory * instance( 0 );
if ( instance == 0 ) {
instance = new MyFactory;
}
return instance;
}
void MyFactory::factory_register( CarCreator * creator )
{
std::list< CarTypes > types = creator->list_cars_I_create();
for ( std::list< CarTypes >::const_iteator iter = types.begin();
iter != types.end(); ++iter ) {
car_creator_map[ *iter ] = creator;
}
}
Car * MyFactory::create_car( CarType type )
{
if ( car_creator_map[ type ] == 0 ) {
exit();
}
return car_creator_map[ type ]->create_a_car( type );
}
...
:
Miata.cpp
class Miata : public Car {...};
class MiataCreator : public CarCreator {
public:
virtual Car * create_a_car( CarType );
virtual std::list< CarTypes > list_cars_I_create();
private:
static bool register_with_factory();
static bool registered;
};
bool MiataCreator::register_with_factory()
{
MyFactory::get_instance()->factory_register( new MiataCreator );
return true;
}
bool MiataCreator::registered( MiataCreator::register_with_factory() );
...
: , MiataCreator:: registered , , .
, - factory Miata, miata car_creator_map NULL, .
- , - ? , ? CarCreator ; .cpp. , - MyFactory:: factory_register?
?
iall CarCreators , factory, , . , CarCreators , - factory .
...
, , :
1) singleton factory .
a) , .
2) singleton factory , CarCreators (.. )
a) singleton, singleton . , , MiataCreator's::register_with_factory: .