Я пытаюсь реализовать модель персистентности объекта в C ++. Идея состоит в том, что существует объект базы данных, который действует как фабрика для различных объектов PersistentObject, каждый из которых связан со строкой в таблице базы данных. База данных имеет такой метод:
PersistentObject *Database::GetObject(int ID);
Это возвращает указатель на объект с предоставленным идентификационным номером (или нулевой указатель, если идентификатор не существует). В классе Database есть также карта всех созданных объектов PersistentObject:
std::map<int, PersistentObject*> _objectMap;
Внутренне, GetObject делает одну из двух вещей:
Если это первый раз, когда запрашивается объект PersistentObject с идентификатором, тогда он запрашивает базу данных, создает новый экземпляр PersistentObject на основе результата, вставляет адрес этого объекта в карту (с идентификатором в качестве ключа) и возвращает указатель на новый объект.
Если объект PersistentObject был ранее загружен (т. Е. Идентификатор уже существует в качестве ключа на карте), он просто возвращает указатель на этот объект.
Причина для централизованного отслеживания PersistentObjects заключается в том, что у меня есть другой поток, который непрерывно опрашивает базу данных на предмет изменений в загруженных PersistentObjects и отправляет событие любому объекту, который устарел.
Что я хочу сделать, так это собрать мусор центральную карту объектов в базе данных, чтобы, когда в клиентском коде не осталось ссылок на определенный объект, объект был удален из карты и удален, и больше не проверялся. потоком мониторинга обновлений.
Я думал сделать это с shared_ptr, но проблема в том, что если я использую shared_ptr на карте, то счетчик ссылок никогда не обнуляется, даже если объект больше не используется. Я не могу сохранить традиционный указатель на PersistentObject на карте и создать из него несколько shared_ptrs.
Кто-нибудь знает способ сделать это? Мне почти нужен shared_ptr, который будет вызывать средство удаления, когда счетчик ссылок достигнет 1, а не 0. Или есть лучший способ добиться того, что я пытаюсь сделать?
Лучший способ должен быть вернуть shared_ptr
клиенту, но хранить weak_ptr
в вашей карте. weak_ptr
не увеличивать счетчик ссылок и может легко произвести больше shared_ptr
с помощью lock()
, Вам придется следить за сроком действия ваших объектов, за исключением того, что вы внедрили пользовательское средство удаления, которое очищает «мертвую» ссылку.
Других решений пока нет …