首页 > 解决方案 > 使用 find C++ 时,地图中的对象为空

问题描述

当我尝试获取对象时,我将对象放入地图(下面的代码)中,对象为空!

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

服务器是 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);
};

这是命令

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

注意:commands[index] 返回一个字符串,当我在推送对象后调试时,我在地图内看到它,但是当我使用 find iterator it->second 返回空对象命令

有任何想法吗?谢谢

更新:我认为问题在于地图找到的对象不是服务器对象,我想在地图中推送许多继承命令的类,并且每个类都运行自己的 execute() 并拥有自己的字段地图返回的命令作为命令类返回,它应该作为服务器返回

最后一个问题:我想使用共享指针作为解决方案我有像 Server 这样继承自 Command 的类,我想将它们放在地图中,然后运行他们自己的 execute(),如上图所示

标签: c++dictionary

解决方案


问题是您将Server对象存储为基本类型的地图值Command。此操作从实例中切Server分所有字段,只留下基类中的字段。

解决这个问题的通常方法是在裸对象的映射实例中存储指向基类的指针,并使用虚拟接口。因此,我建议您在派生类中使用其特定实现进行int execute(vector<string> inputs);虚拟化并覆盖它。Server在地图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);
        }
}

推荐阅读