#include <iostream>#include <vector>class BaseCommand { public: enum CommandType { TypeA, TypeB }; BaseCommand() = default; virtual void execute() = 0; virtual bool dublicated() = 0; virtual BaseCommand::CommandType commandType() = 0;};class CommandA : public BaseCommand { public: CommandA() = default; void execute() override { std::cout << "execure CommandA" << std::endl; } bool dublicated() override { return true; } BaseCommand::CommandType commandType() { return TypeA; }};class CommandB : public BaseCommand { public: CommandB() = default; void execute() override { std::cout << "execure CommandB" << std::endl; } bool dublicated() override { return false; } BaseCommand::CommandType commandType() { return TypeB; }};std::vector<BaseCommand *> m_arr;bool checkCommand(BaseCommand *command){ if (!command) return false; if (!command->dublicated()) { for (std::vector<BaseCommand *>::iterator it = m_arr.begin() ; it != m_arr.end(); ++it) if ((*it)->commandType() == command->commandType()) { return false; } } m_arr.push_back(command); return true;}int main(int argc, char *argv[]){ CommandA *ca = new CommandA; if (checkCommand(ca)) { ca->execute(); }else { delete ca; } CommandB *cb = new CommandB; if (checkCommand(cb)) { cb->execute(); }else { delete cb; } return 0;}
bool checkCommand(BaseCommand::CommandType type){ for (std::vector<BaseCommand *>::iterator it = m_arr.begin() ; it != m_arr.end(); ++it) if ((*it)->commandType() == type) { return false; } } return true;}
int main(int argc, char *argv[]){ if ( checkCommand( BaseCommand::TypeA ) ) m_arr.push_back( new CommandA );...}
class BaseCommand{... static bool dublicated ( Type type ) { switch ( type ) { ... } }};
C++ (Qt)template <class Command>std::shared_ptr<BaseCommand> createCommand(){ std::shared_ptr<BaseCommand> command = std::make_shared<Command>(); if (!command->dublicated()) { for (std::vector<BaseCommand *>::iterator it = m_arr.begin() ; it != m_arr.end(); ++it) if ((*it)->commandType() == command->commandType()) { return null_ptr; } } m_arr.push_back(command); return command;} int main(int argc, char *argv[]){ auto ca = createCommand<CommandA>(); if (ca) ca->execute(); auto cb = createCommand<CommandB>(); if (cb) cb->execute(); return 0;}
C++ (Qt)#include <iostream>#include <string>#include <boost/variant.hpp>#include <memory>#include <vector> struct typeA_teg{};struct typeB_teg{}; class BaseCommand{public: typedef boost::variant<typeA_teg, typeB_teg> command_type; BaseCommand() = default; virtual void execute() = 0; virtual command_type commandType() = 0;}; class CommandA : public BaseCommand { public: CommandA() = default; void execute() override { std::cout << "execure CommandA" << std::endl; } BaseCommand::command_type commandType() { return typeA_teg(); }}; class CommandB : public BaseCommand { public: CommandB() = default; void execute() override { std::cout << "execure CommandB" << std::endl; } BaseCommand::command_type commandType() { return typeB_teg(); }}; template <class>struct command_traits; template <>struct command_traits<CommandA>{ static constexpr bool is_dublicated = true; typedef typeA_teg command_type;}; template <>struct command_traits<CommandB>{ static constexpr bool is_dublicated = false; typedef typeB_teg command_type;}; template <class Command>struct is_same_command_type : public boost::static_visitor<bool>{ typedef typename command_traits<Command>::command_type command_type; bool operator()(command_type) const { return true; } template <class T> bool operator()(T) const { return false; }}; std::vector<std::shared_ptr<BaseCommand>> m_arr; template <class Command>bool checkCommand(){ if (!command_traits<Command>::is_dublicated) { for (auto & c : m_arr) { if (boost::apply_visitor(is_same_command_type<Command>(), c->commandType()) return false; } } m_arr.push_back(std::make_shared<Command>()); return true;}
C++ (Qt)#include <iostream> using namespace std; template<bool isDup>class Command{public: static bool dublicated() { return isDup; }}; class CommandA : public Command<true>{}; class CommandB : public Command<false>{}; int main(){ cout << CommandA::dublicated() << endl; cout << CommandB::dublicated() << endl; return 0;}