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

c++ generic storage and retrieval of objects using string handle

本文关键字:存储 检索 对象 字符串 句柄 c++      更新时间:2023-10-16

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

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

例如,用户定义的类是

class Dog : public Object{
public:
Dog(){};
Dog(std::string name){dogName=name};
~Dog(){};
std::string dogName;
//...
}
class Cat : public Object{
public:
Cat(){};
Cat(std::string name){catName=name};
~Cat(){};
std::string catName;
//...
}

并且执行以下代码

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'
}

我认为应该有一些既定的想法(模式)来使这一点发挥作用。

我还怀疑std::shared_ptr在这里可能有用。

谢谢,

我在这里要小心,在您的示例中,您将对象严格地存储为Object(在堆栈上),因为这只会为对象类型的东西分配足够的空间,如果您插入从该类型继承的东西,它将对描述子类的部分进行切片。

手头问题的好例子:

  • http://www.geeksforgeeks.org/object-slicing-in-c/
  • 什么是对象切片

解决这个问题的一种方法是处理指向ObjectHandler中对象的指针,对象本身在堆上分配。

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

但是,如果你像你说的那样,将存储指向对象的智能指针,那么制作一对指针应该是这样的:

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

根据您希望在什么时候开始使用智能指针处理对象,插入可能看起来像:

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::string handle, std::shared_ptr<Object> obj){
_obj.insert(std::make_pair(handle, obj));
}

还要注意,std::map的索引运算符[]会覆盖旧值(如果它存在),而您已经使用的insert只会在旧值不存在的情况下插入。