Вы описываете заводскую функцию.Есть много способов сделать это, от реестров до простых цепочек if/else
.
Обычно ваш класс Image
является производным от аналогичного базового класса для других типов, анализируемых в.Таким образом, вы можете добавить их все в один контейнер.
Представьте себе эту иерархию:
class Media {
public:
virtual Save() = 0;
};
class Image : public Media {
public:
Image() { }
virtual Save() { ... }
};
class Sound : public Media {
public:
Sound() { }
virtual Save() { ... }
};
Самая простая конструкция - это фабричная функция:
Media *CreateMedia(const string &type) {
if (type == "Image") {
return new Image;
} else if (type == "Sound") {
return new Sound;
} else {
// handle invalid type error
}
}
Другойальтернатива - использовать реестр, вместо CreateMedia
вы обычно используете макрос, фабрику / реестр и какой-то механизм для создания своих подклассов:
// This is some mechanism to create types of Media.
template <typename T>
struct CreatorFunction {
Media *operator() {
return new T;
}
};
// This is the factory that the types will register with.
class Factory {
public:
// singleton access function.
static Factory* Get() {
static Factory* f = new Factory;
return f;
}
// Creates Media of the given type.
Media* Create(const string& name) { return registry_[name](); }
// Records 'name' with the creator function 'func'.
void Add(const string& name, const CreatorFunction &func) {
registry_.insert(name, func);
}
private:
Factory() { } // users can't create factories, they can only use singleton.
hash_map<string, CreatorFunction> registry_;
};
#define REGISTER_MEDIA(type) Factory::Get()->Add(#type, CreatorFunction<type>);
REGISTER_MEDIA(Image); // usually goes with the Image class.
REGISTER_MEDIA(Sound); // usually goes with the Sound class.
int main(int argc, char** argv) {
string parsedIn = "Image";
Factory::Get()->Create(parsedIn);
}
В целом это более чистый подход, но вы можетевозникли проблемы с вашим компоновщиком, который думает, что некоторые символы не используются, и удаляет важные зарегистрированные классы из вашего двоичного файла.Возможно, вы захотите придерживаться цепочки if/then
, пока вам не понадобится что-то более сложное.Обычно вы обращаетесь к реестрам, когда невозможно иметь единственное место, где определены все подтипы.