C++ c++;使用字符串句柄对对象进行通用存储和检索

C++ c++;使用字符串句柄对对象进行通用存储和检索,c++,object,design-patterns,handler,handle,C++,Object,Design Patterns,Handler,Handle,实现泛型对象(所有其他对象都从基继承)存储的优雅而简单的方法(如果存在)是什么。存储对象后,使用字符串句柄检索对象或复制到另一个对象中 class Object{ public: Object(){}; ~Object(){}; }; class ObjectHandler{ public: ObjectHandler(){}; ~ObjectHandler(){}; void InsertObje

实现泛型对象(所有其他对象都从基继承)存储的优雅而简单的方法(如果存在)是什么。存储对象后,使用字符串句柄检索对象或复制到另一个对象中

class Object{
    public:
        Object(){};
        ~Object(){};
};

class ObjectHandler{
    public:
        ObjectHandler(){};
        ~ObjectHandler(){};
        void InsertObject(std::string handle, std::shared_ptr<Object> obj){
            // some things happen before inserting
            _obj.insert(std::make_pair(handle,obj));
        }
        std::shared_ptr<Object> RetrieveObject(std::string handle){
            // some things happen before retrieving
            return _obj[handle];
        }
    private:
        std::map<std::string,std::shared_ptr<Object>> _obj;

}
然后执行以下代码

void main(){
    ObjectHandler oh;
    Cat c("kitten"), cc;
    Dog d("doggy"), dd;

    oh.InsertObject("cat#1",c);
    oh.InsertObject("dog#1",d);

    cc = oh.RetrieveObject("cat#1");
    dd = oh.RetrieveObject("dog#1");

    std::cout << cc.catName << std::endl; // expect to print 'kitten'
    std::cout << dd.dogName << std::endl; // expect to print 'doggy'
}
void main(){
噢,;
c类(“小猫”)、cc;
狗d(“狗”),dd;
oh.InsertObject(“第1类”,c);
插入对象(“dog#1”,d);
cc=oh.RetrieveObject(“cat#1”);
dd=oh.RetrieveObject(“dog#1”);

std::cout我在这里要谨慎,在您的示例中,您将对象存储为对象(在堆栈上),因为这只会为Object类型的内容分配足够的空间,所以如果插入从该类型继承的内容,则会将描述子类的部分切片

当前问题的好例子:

解决此问题的一种方法是处理指向对象处理程序中对象的指针,而不是在堆上分配对象本身

如果我只是误解了你的帖子,那么我道歉

但是,如果您如您所说,将存储指向对象的智能指针,则创建一对指针应该如下所示:

std::map<std::string,std::shared_ptr<Object>> _obj;;
std::string handle = "hello"; //Or whatever the actual handle is.
std::shared_ptr<Object> keyvalue(new Object());

objects[handle] = std::shared_ptr<Object>(keyvalue); //alternative to std::make_pair
objects.insert(std::make_pair(handle, std::shared_ptr<Object>(keyvalue))); //this also works
std::map;;
std::string handle=“hello”//或任何实际句柄。
std::shared_ptr keyvalue(new Object());
objects[handle]=std::shared_ptr(keyvalue);//std::make_pair的替代方案
insert(std::make_pair(handle,std::shared_ptr(keyvalue));//这同样有效
根据您希望在什么点开始使用智能指针处理对象,插入可能如下所示:

    void InsertObject(std::string handle, Object* obj){
        _obj.insert(std::make_pair(handle,std::shared_ptr<Object>(obj)));
    }

    std::string key("hi");
    InsertObject(key, new Object());
void InsertObject(std::字符串句柄,Object*obj){
_对象插入(std::make_pair(handle,std::shared_ptr(obj));
}
字符串键(“hi”);
InsertObject(键,新对象());
或者只是:

    void InsertObject(std::string handle, std::shared_ptr<Object> obj){
        _obj.insert(std::make_pair(handle, obj));
    }
void InsertObject(std::字符串句柄,std::shared\u ptr obj){
_obj.插件(标准::制作成对(手柄,obj));
}

还请注意,如果旧值存在,std::map的索引运算符[]将覆盖旧值,而您正在使用的insert将仅在旧值不存在时插入。

A
map
如果可以,我们将有
std::map\u obj;
,但如何将一对插入到map中?\u obj.insert(std::make\u pair(handle,obj));你从来没有接受过我的回答,顺便说一句:Dcool!谢谢你的详细建议。我已经用shared#ptr编辑了第一篇帖子,看起来不错。剩下的最后一步是找出“cc=oh.RetrieveObject”(“cat#1”)'如何处理返回的共享\u ptr并获取对象实例..您只需取消引用指针,就可以直接引用对象,共享\u ptr已重载*运算符。*
object obj;Dog dd;obj=*(oh.RetrieveObject(h));
但它返回type=Object。当我想找回我的狗时,编译器会抱怨
操作符=
dd=*(哦,RetrieveObject(h));
。我会遇到您上面提到的切片问题吗?是的,您会的,请注意,在返回超类型的内容时,如果不对子类型进行强制转换,您将无法访问子类型唯一的成员。别忘了将析构函数设为虚拟。这很重要!
    void InsertObject(std::string handle, std::shared_ptr<Object> obj){
        _obj.insert(std::make_pair(handle, obj));
    }