Reputation: 86
As I can't use the real code, I'll try to sketch the situation using a simplified pseudo-code example:
class Factory {
public:
System& build(const Input& input) {
if (input.getType() == "Airplane") return Airplane(input.getNrWheels);
if (input.getType() == "Car") return Car(input.getNrWheels);
}
}
Both Car and Airplane inherit from System;
We use this factory in two executables. As executable 1 can be used with Cars and executable 2 can be used with Airplanes. We would like to be able to compile and link executable 1 with Factory and Car and executable 2 with Factory and Airplane. What should we do with the Factory class to enable this?
EDIT: Change after comments/answers
This is less simplified example showing my problem more clearly:
class Factory {
public:
System& build(const Input& input) {
if (input.Airplane()) {
Pilot& pilot = *new Pilot();
AutoPilot& autoPilot = *new AutoPilot();
return Airplane(input.Airplane()->NrWheels(), pilot);
}
if (input.Car()) {
Driver& driver = *new Driver();
return Car(input.Car()->NrWheels, driver);
}
}
}
I like the answer below which suggests the constructor map, but I (think I) need a version which allows different arguments for the constructors. I also would like to keep Car and Airplane free of dependency on Input.
Upvotes: 0
Views: 99
Reputation: 146930
Cut it out completely. The Factory class serves literally no benefit at all when it can only create one kind of thing. Just use a typedef instead to be flexible about what kind of System you are creating.
Upvotes: 0
Reputation: 16737
Use something like a std::map<std::string, std::function<System(T)> ctorMap;
where T
is the type of Input::getNrWheels
, inside Factory
to hold the appropriate constructors, indexed by strings. Also provide a method, say Factory::Register(std::string, std::function<System(T))
which any class can use to register its constructor. So, the TU which defines Airplane
should ensure that there is a call, during static initialization, for example, Factory::Register("Airplane", std::make_function(&Airplane::Airplane))
.
Also, Factory::build
would now look like this:
System& build(const Input& input) {
return ctorMap[input.getType()](input.getNrWheels);
}
Upvotes: 1