Итак, у меня есть абстрактный класс User и различные типы пользователей, которые являются его производными. из него.
Затем у меня есть класс CommandInterface [принимает входные строки (пользовательский ввод разделен на строки в основном? (stringstream)], который содержит указатель на loggedInUser базового класса типа (User * loggedInUser) и имеет команды:
- login [имя] // позволяет «регистрировать» интерфейс под этим пользователем
- signup [имя] [возраст] [пароль] и т. д. // Добавляет пользователя в саму систему (другой класс)
- exit // Выходит из системы, если вошел в систему, или выключается интерфейс, если нет
Пользователь1: у пользователя есть метод a();
Пользователь2: у пользователя есть метод b() ;
Теперь как я могу вызывать разные методы разных пользователей, имея только указатель типа User (базовый класс)?
Код ( c++/псевдо):
Код: Выделить всё
#include
#include
#include
#include
class CommandInterface {
static unordered_map> interfaceCommands = {...};
std::shared_ptr loggedUser = nullptr;
// Singleton
static CommandInterface* instance;
CommandInterface() = default;
std::unique_ptr sys = System::getInstance(); // Instance to system which holds users (also singleton)
public:
// Singleton
CommandInterface(const CommandInterface& other) = delete;
CommandInterface(CommandInterface&& other) = default;
CommandInterface& operator=(const CommandInterface& other) = delete;
CommandInterface& operator=(CommandInterface&& other) = default;
~CommandInterface() = default;
static CommandInterface* getInstance();
// Commands
void signup(const std::string& name, uint8_t age, std::string& userType); // Adds users to System
void login(const std::string& name) {
if(loggedUser) {
throw std::exception();
}
else {
loggedUser = sys->getUser(name);
}
}
void exitCmd() {
if(loggedUser) {
loggedUser = nullptr;
}
else {
// Will be caught so that all the destructors are called
// Since std::exit(0) won't call the destructors
throw std::runtime_error("Exit.");
}
}
std::shared_ptr &getLoggedUser(); // Getter, used by the commands
void executeCommand(const std::string& command, const std::vector& args) {
if(!loggedUser) {
// Throw exception if command doesn't exist
interfaceCommands[command]->execute(args);
}
else {
// Throw exception if command doesn't exist (different users also hold static map of their commands to check)
loggedUser->getCommand(name)->execute(args); // Some pure virtual method
}
}
};
class Command {
public:
virtual ~Command() = default;
virtual void execute(const std::vector& args) const = 0;
};
class PrintCMD : public Command {
public:
void execute(const std::vector& args) const override {
CommandInterface::getInstance()->getLoggedUser()->print();
}
};
class ACMD : public Command {
public:
void execute(const std::vector& args) const override {
CommandInterface::getInstance()->getLoggedUser()->a(); // Error Here
}
};
class BCMD : public Command {
public:
void execute(const std::vector& args) const override {
CommandInterface::getInstance()->getLoggedUser()->b(); // Error Here
}
};
Итак, проблема в том, как бороться с полиморфизмом, который «затеняет» методы производных классов?
Подробнее здесь: https://stackoverflow.com/questions/786 ... lymorphism