Каким будет элегантный и простой способ (если существует) для реализации хранилища общих объектов (все остальные объекты наследуются от базы). После сохранения объекта используйте дескриптор строки для извлечения объекта или копирования в другой.
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, если вы вставляете что-то, что наследует от типа, оно будет иметь часть, описывающая нарезку подкласса.
Хорошие примеры проблемы:
Один из способов обойти эту проблему состоит в том, чтобы обрабатывать указатели на объекты в объекте 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 indexing [] перезаписывает старое значение, если оно существует, а вставка, которую вы уже используете, будет вставляться только в том случае, если старый не существует.
map<string, shared_ptr<Object>>
должна работатьstd::map<std::string,std::shared_ptr<Object>> _obj;
, но как бы мы сделали пару, чтобы вставить в карту? _obj.insert (std :: make_pair (handle, obj ));