Где удалить объект, созданный factory?
Если у меня есть factory, который создает объект и возвращает указатель на него, что будет лучшим способом его удалить:
В качестве delete
вызывается код пользователя или новая функция DestructObject
, которую я должен иметь вместе с factory?
Ответы
Ответ 1
В общем случае factory может не использовать простой старый new
для размещения объекта. Он может использовать пул объектов и/или страниц, malloc
с местом размещения new
, или что-то еще более экзотическое (отображение памяти?). Есть как минимум три способа справиться с этим, о чем я могу думать:
- Попросите factory предоставить метод
recycle
для вызова, когда вы закончите с этим объектом.
- Верните умный указатель, который знает, как покончить с объектом, когда референты не останутся.
- Внедрить собственный
delete
оператор в самом объекте.
Я стесняюсь рекомендовать один за другим, так как я не думал об этом за последние пять минут, чтобы предложить окончательное мнение, но я бы предпочел использовать последний вариант в сочетании с обычным умным указателем, таким как boost/tr1:: shared_ptr.
Ответ 2
Лучший способ удалить его вручную - не на всех.
Ответ 3
Следующий код дает возможность не думать о том, кто должен удалить вновь созданный объект.
class FooFactory
{
public:
static std::auto_ptr<Foo> CreateInstance();
};
// transmit ownership of created object from factory to 'a' variable
std::auto_ptr<Foo> a = FooFactory::CreateInstance();
// using the created object is not required
FooFactory::CreateInstance();
Ответ 4
Наиболее универсальным решением этой проблемы является извлечение вашего класса из базового класса, который имеет виртуальную функцию "убийства". Что-то вроде этого:
class IDisposable {
public:
virtual void Release() = 0;
};
В целом считалось, что полиморфные объекты должны иметь виртуальные деструкторы для поддержки надлежащей очистки объекта. Однако это неполное, поскольку оно не учитывает потенциально различное управление памятью объектов.
С другой стороны, этот метод не требует использования виртуальных деструкторов. Теперь он заменяется функцией Release
, которая выполняет оба действия: вызов правильного деструктора и освобождение памяти соответствующими средствами.
заботится об объекте destr
both: destruct
Объект, возвращенный из factory, реализует этот "интерфейс".