c ++ универсальное хранение и поиск объектов с использованием дескриптора строки

0

Каким будет элегантный и простой способ (если существует) для реализации хранилища общих объектов (все остальные объекты наследуются от базы). После сохранения объекта используйте дескриптор строки для извлечения объекта или копирования в другой.

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 может быть полезен здесь.

Благодаря,

  • 0
    map<string, shared_ptr<Object>> должна работать
  • 0
    поэтому у нас будет std::map<std::string,std::shared_ptr<Object>> _obj; , но как бы мы сделали пару, чтобы вставить в карту? _obj.insert (std :: make_pair (handle, obj ));
Показать ещё 2 комментария
Теги:
object
handler
design-patterns
handle

1 ответ

1
Лучший ответ

Я бы проявил осторожность здесь, в вашем примере вы сохраняете свои объекты как Объект строго (в стеке), так как это будет выделять достаточно места для чего-то типа 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 [] перезаписывает старое значение, если оно существует, а вставка, которую вы уже используете, будет вставляться только в том случае, если старый не существует.

  • 0
    прохладно! спасибо за подробное предложение. я исправил первое сообщение с shared_ptr <Object>. Скомпилировано, выглядит хорошо. последний оставленный шаг - выяснить 'cc = oh.RetrieveObject ("cat # 1"); как поступить с возвращенным shared_ptr <Object> и получить вместо него экземпляр объекта ..
  • 0
    Вы можете просто разыменовать указатель, и вы получите прямую ссылку на объект, shared_ptr перегружен * оператором. en.cppreference.com/w/cpp/memory/shared_ptr/operator *
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню