Если у меня есть фабрика, которая создает объект и возвращает указатель на него, каким будет лучший способ его удалить:
Вызовом delete
в "пользовательском" коде или новой функцией DestructObject
, которая должна быть у меня вместе с фабрикой?
Если у меня есть фабрика, которая создает объект и возвращает указатель на него, каким будет лучший способ его удалить:
Вызовом delete
в "пользовательском" коде или новой функцией DestructObject
, которая должна быть у меня вместе с фабрикой?
В общем случае фабрика может не использовать старый добрый new
для размещения объекта. Он может использовать объединение объектов и/или страниц, malloc
с размещением new
или что-то еще более экзотическое (отображение памяти?). Есть по крайней мере три способа справиться с этим, о которых я могу думать:
recycle
, который будет вызываться, когда вы закончите работу с объектом.delete
в самом объекте.Я не решаюсь рекомендовать один вариант другому, так как за последние пять минут я недостаточно подумал, чтобы высказать окончательное мнение, но я бы предпочел последний вариант в сочетании с обычным интеллектуальным указателем, таким как boost/tr1: :shared_ptr.
delete
, который всегда находится в безопасности.
- person Marcelo Cantos; 11.07.2010
delete
по умолчанию, который будет вызывать любой базовый распределитель памяти, связанный с вызывающим кодом. Если аллокатор связан статически с любой стороны (или просто два разных аллокатора связаны динамически), то неприятные сбои не за горами. Также обратите внимание, что пользовательский delete
, о котором я говорю, должен быть скомпилирован в библиотеку, поэтому его нельзя объявлять inline
.
- person Marcelo Cantos; 12.07.2010
delete
код работает хорошо... Большое спасибо за пояснение.
- person jdehaan; 12.07.2010
Лучшим способом удалить его вручную будет вовсе нет а>.
Следующий код дает возможность не думать о том, кто должен удалить только что созданный объект.
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();
Наиболее универсальным решением этой проблемы является получение вашего класса от базового класса, который имеет виртуальную «убийственную» функцию. Что-то вроде этого:
class IDisposable {
public:
virtual void Release() = 0;
};
Обычно считается, что полиморфные объекты должны иметь виртуальные деструкторы для поддержки правильной очистки объекта. Однако это неполно, поскольку не учитывает потенциально различное управление памятью объектов.
С другой стороны, этот метод не требует использования виртуальных деструкторов. Теперь она заменена функцией Release
, которая делает и то, и другое: вызов правильного деструктора и освобождение памяти соответствующими средствами.
заботится об уничтожении объекта
оба: уничтожить
Объект, возвращенный с фабрики, будет реализовывать этот «интерфейс».