Управление памятью с помощью шаблона команд

Итак, у меня есть следующая реализация шаблона команд, которая содержится в std::map<CString, IWrite*> commandMap:

class IWrite
{
protected:
CStdioFile* fileWriter;

public:
IWrite(CStdioFile* _fileWriter)
: fileWriter(_fileWriter)
{
}

virtual ~IWrite()
{
}

virtual BOOL exec() = 0;
};

class FloatWrite : public IWrite
{
private:
float input;

public:
FloatWrite(CStdioFile* _fileWriter, float _input)
: IWrite(_fileWriter), input(_input)
{
}

BOOL exec()
{
CString fieldvalue;
fieldvalue.Format("%f", input);
fileWriter->WriteString(fieldvalue);

return TRUE;
}
};

У меня проблема в том, что мой инструмент статического анализа жалуется, что fileWriter не освобождается или обнуляется в деструкторе IWrite, Тем не менее, добавив delete fileWriter в деструкторе я получаю ошибку доступа к памяти при удалении объекта шаблона команды на карте перед вызовом std::map.clear() как показано ниже:

// free map memory
for ( std::map<CString, IWrite*>::iterator mapItr = commandMap.begin();
mapItr != commandMap.end();
++mapItr)
{
delete mapItr->second;
}
commandMap.clear();

Я неправильно подхожу к управлению памятью? Я не очень много работал с картами STL, поэтому я не знаком с идиоматическим подходом.

РЕДАКТИРОВАТЬ: Как я добавляю элементы на карту:

void FooClass::initCommandMap(const MSG_DATA_STRUCT * msgdata)
{
// Write a float, foo
commandMap[_T("foo")] = new FloatWrite(&fileWriter, msgdata->foo);
// Write an unsigned int, bar
commandMap[_T("bar")] = new UIntWrite(&fileWriter, msgdata->bar);
// etc...
}

Это вызывается каждый раз, когда пользователь выбирает для записи данных, поэтому fileWriter объект, используемый различными exec()‘s является текущим с файлом, выбранным пользователем.

Обратите внимание, что CStdioFile fileWriter является переменной-членом FooClass,

1

Решение

Почему вы держите указатель на fileWriter? Из того, что я вижу, ваш объект Command предполагает, что писатель должен существовать до использования команды. Он также не должен пытаться управлять объектом записи, так как он может использоваться несколькими объектами команд.
Попробуйте сохранить ссылку вместо этого.

class IWrite
{
protected:
CStdioFile &fileWriter;

public:
IWrite(CStdioFile &_fileWriter)
: fileWriter(_fileWriter)
{
}

virtual ~IWrite()
{
}

virtual BOOL exec() = 0;
};
1

Другие решения

Других решений пока нет …