Я пытаюсь (каким-то образом) кэшировать несколько итераций на std :: map, когда мне нужно вставить несколько значений с помощью этого метода:
enum PROPERTY_TYPE
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_UNSIGNED,
TYPE_FLOAT,
TYPE_STRING
};
struct Property {
Property(PROPERTY_TYPE type)
: type(type), bool_val(false), integer_val(0), unsigned_val(0), float_val(0.0f), string_val("")
{ }
PROPERTY_TYPE type;
bool bool_val;
int integer_val;
unsigned int unsigned_val;
float float_val;
std::string string_val;
};
std::map< std::string, Property* > _Properties;
void pushBool(std::string key, bool value)
{
std::pair< std::map< std::string, Property* >::iterator, bool > pItr;
pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );
// If the value doesn't exist then it created automatically or the existion one is used.
pItr.first->second->bool_val = value;
pItr.first->second->integer_val = value ? 1 : 0;
pItr.first->second->unsigned_val = value ? 1 : 0;
pItr.first->second->float_val = value ? 1.0f : 0.0f;
pItr.first->second->string_val = value ? "true" : "false";
}
Это самый быстрый и безопасный способ заставить его работать до сих пор. Однако меня интересует одна мелочь и функция insert(). Когда я вызываю новое свойство (TYPE_BOOLEAN), я четко создаю новое свойство(), которое никто не контролирует. И из того, что я читал, std :: map не вызывает удаление указателей при отбрасывании. И когда я использую этот метод вставки, функция insert использует существующее значение, если оно уже существует. Итак, кто удаляет это вновь созданное свойство(), если значение уже существует и оно используется вместо нового?
pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );
Будет ли этот метод пустой тратой памяти путем введения утечек памяти?
Вы правы - std::map
не покупает вопрос о том, кто удаляет любые указатели, которые он хранит, - он ожидает, что клиентский код возьмет на себя ответственность или сохранит тип, который делает это по своей сути. Самый простой и часто лучший способ сделать это - то, как вы использовали бы, если бы не видели ясную причину, в противном случае - хранить "семантический" тип значения - тот, который заботится о своей собственной жизни, и может быть копируются интуитивно, ведут себя так же, как int
или другой встроенный тип в этом отношении.
В вашем случае там, по-видимому, нет причин использовать указатели вообще... просто
std::map< std::string, Property > _Properties;
Если вам все равно, вставляете ли вы новый элемент или обновляете старый:
Property& p = _Properties[key];
p.bool_val = value;
p.integer_val = ... etc
Отдельно, если идея состоит в том, что Property концептуально хранит любой из этих типов данных, вы можете найти boost::variant
полезным: http://www.boost.org/doc/libs/1_55_0/doc/html/variant. HTML
Да, эта линия может вызвать утечку.
Либо хранить интеллектуальные указатели, либо проверить наличие перед вставкой. Я бы посоветовал умные указатели. unique_ptr
вероятно, для указания права собственности.
В этом конкретном случае свободное распределение ресурсов - плохая идея, но я полагаю, что у реальной проблемы есть причина хранить там предметы.
map< string, unique_ptr<Properties>>
не помогает, потому что почему?
_Properties
в клиентском коде C ++ запрещено .