объект пуст в карте при использовании find C ++ - PullRequest
0 голосов
/ 29 января 2020

Я помещаю объекты в карту (код ниже), когда я пытаюсь получить его, объект пуст!

Server s;
s.port = 5400;
commandsMap.insert(std::pair<string,Command>("openDataServer",s));

Сервер присущ команде

class Server: public Command{
public:
    static map<string,Varinfo> symbolList;
    static map<string,Command> commandsMap;

    bool stop = false;
    int port;
    int execute(vector<string> inputs);
    static int lstn(int socketfd,sockaddr_in address);
};

и Вот команда

class Command{
public:
    Command();
    int execute(vector<string> inputs);
};

, и здесь я пытаюсь найти значения, которые я там выдвинул, но объект из класса Command и его пустой!

 auto it = commandsMap.find(commands[index]);
        if ( it != commandsMap.end() ) {
            index += it->second.execute(commands);
        }

note: command [index] возвращает строку, и когда я отлаживаю после нажатия объекта, я вижу его прямо внутри карты, но когда я использую find iterator it-> second возвращает пустой объект Command

есть идеи? спасибо

Обновление: я думаю, проблема в том, что объект, который карта находит, не является объектом сервера, я хочу добавить в карту sh много типов классов, которые наследуют Command, и каждый из которых запускается свой собственный execute () и иметь собственные поля. Команда, которую возвращает карта, возвращается как класс команд, она должна возвращаться как сервер

final Вопрос: я хочу использовать общий указатель в качестве решения У меня есть классы, такие как Server, которые наследуются от Command, я хочу поместить их в карту, а затем запустить свою собственную execute (), как показано выше

1 Ответ

0 голосов
/ 29 января 2020

Проблема в том, что вы сохраняете объект Server как значение карты базового типа Command. Эта операция вырезает из Server экземпляра все поля и оставляет только поля из базового класса.

Обычным решением этой проблемы является сохранение указателя на базовый класс в экземпляре карты голого объекта, а также использование виртуального интерфейс. Поэтому я предлагаю вам сделать виртуальный int execute(vector<string> inputs); и переопределить его в производном классе Server с его конкретной реализацией c. На карте используйте std::unique_ptr<Command> в качестве значения:

https://coliru.stacked-crooked.com/a/df5fa3a97f897977

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
using namespace std;

struct Varinfo{};
struct sockaddr_in{};
class Command{
public:
    Command() {}
    virtual int execute(vector<string> inputs) {
         std::cout << "From: Command" << std::endl;
        return 0;}
};

class Server: public Command{
public:
    static map<string,Varinfo> symbolList;
    static map<string,Command> commandsMap;

    bool stop = false;
    int port;
    int execute(vector<string> inputs) override { 
        std::cout << "From: server: port = " << port << std::endl;
        return 0;}
    static int lstn(int socketfd,sockaddr_in address){return 0;}
};

int main()
{ 
    std::map<std::string, std::unique_ptr<Command>> commandsMap;

    auto server_ptr = std::make_unique<Server>();    
    server_ptr->port = 5400;

    commandsMap.emplace("openDataServer", std::move(server_ptr));
    // or: commandsMap.emplace("openDataServer", std::make_unique<Server>(...));

    int index = 0;
    std::vector<std::string> commands = {"openDataServer"};
    auto it = commandsMap.find(commands[index]);
        if ( it != commandsMap.end() ) {
            index += it->second->execute(commands);
        }
}
...