Имеется класс команда и куча производных от него конкретных команд:
class Command {
public:
enum Type {
Command1,
Command2,
etc..
};
Command(Type type) : type_(type) { }
virtual ~Command() = 0;
Type type() const { return type_; }
private:
Type type_;
};
class ConcreteCommand1 : public Command {
public:
ConcreteCommand1(int argument) : Command(Command1), argument_(argument) { }
int argument() const { return argument_; }
private:
int arguement_;
};
Имеется класс, который должен содержать очередь таких команд, у которого есть метод добавления команды в очередь:
class CommandExecutor {
public:
void enqueueCommand(const Command* command);
private:
std::queue<Command*> inputQueue_;
};
Т.к. классов команд несколько, приходится хранить в очереди не сами объекты, а указатели на них. CommandExecutor после выборки команды из очереди и ее исполнения просто уничтожает соответствующий объект. Получается, что для передачи команды в CommandExecutor::enqueueCommand необходимо создать объект конкретной команды в куче. Собственно ничего не мешает это сделать, но хочется писать код, который сложно использовать неправильно. В данном случае придется откомментировать enqueueCommand, обозначив необходимость создания объектов Command в куче и переход права владения на объект к CommandExecutor. Ну а теперь собственно сам вопрос: как лучше решается такая проблема? Исключительно комментированием условий использования или все же можно сделать реализацию поизящнее?
Мне на ум приходит разве что использование pimpl для Command. Но в этом случае придется создавать кучу дополнительного кода для каждого конкретного класса-команды. Так же можно воспользоваться boost::any, но очень не хочется добавлять дополнительные накладные расходы, т.к. код довольно критичен ко времени выполнения.