-1

I'm putting objects in a map(code below) when i try to get it the object is empty!

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

Server is inherent from Command

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);
};

and here is command

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

and here I'm trying to find the values that I pushed up there, but the object is from class Command and its empty!

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

note: commands[index] returns a string and when I debug after pushing the object I see it right inside the map, but when I use find iterator it->second returns empty object Command

any ideas? thanks

Update: I think the problem is that the object that the map finds its not a server object, I want to push in the map many types of classes that inherts Command, and each one to run its own execute() and to have its own fields the Command that the map returns is returned as Command Class, it should return as Server

final Question: I want to use a shared pointer as a solution I have classes like Server that inherits from Command, I want to put them inside a map, and then run thier own execute() as shown upthere

1 Answers1

0

The problem is that you are storing your Server object as a map value of base type Command. This operation slices from Server instance all the fields and leaves only those from base class.

Usual solution to this problem is to store pointer to base class in the map instance of the bare object, and also use virtual interface. So I suggest you to make int execute(vector<string> inputs); virtual and override it in the Server derived class with its specific implementation. In the map use std::unique_ptr<Command> as the value:

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);
        }
}
marcinj
  • 48,511
  • 9
  • 79
  • 100