Где удалить объект, созданный фабрикой? - PullRequest
14 голосов
/ 11 июля 2010

Если у меня есть фабрика, которая создает объект и возвращает указатель на него, что будет лучшим способом удалить его:

вызовом delete в «пользовательском» коде или новой функцией DestructObject, которую я должен иметь вместе с фабрикой?

Ответы [ 4 ]

13 голосов
/ 11 июля 2010

В общем случае фабрика может не использовать простой старый new для выделения объекта.Он может использовать пул объектов и / или страниц, malloc с размещением new или что-то еще более экзотическое (отображение памяти?).Есть как минимум три способа справиться с этим, о которых я могу подумать:

  1. Попросите фабрику предоставить метод recycle, который будет вызван, когда вы закончите с объектом.
  2. Возвратите умный указатель, который знает, как покончить с объектом, если не осталось ссылок.
  3. Реализуйте пользовательский оператор delete в самом объекте.

Я не решаюсь рекомендовать одинс другой стороны, поскольку в последние пять минут я не придал этому достаточного значения, чтобы высказать окончательное мнение, но я предпочел бы предпочесть последний вариант в сочетании с обычным умным указателем, например boost / tr1 :: shared_ptr.

1 голос
/ 11 июля 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();
1 голос
/ 11 июля 2010

Лучший способ удалить его вручную - это вовсе .

0 голосов
/ 11 июля 2010

Самое универсальное решение этой проблемы - извлечь ваш класс из базового класса, который имеет виртуальную функцию "убийства".Примерно так:

class IDisposable {
public:
    virtual void Release() = 0;
};

Обычно считается, что полиморфные объекты должны иметь виртуальные деструкторы для поддержки правильной очистки объекта.Однако это неполно, поскольку не учитывает потенциально различное управление памятью объектов.

С другой стороны, этот метод не требует использования виртуальных деструкторов.Теперь она заменена функцией Release, которая выполняет оба действия: вызывает правильный деструктор и освобождает память соответствующими средствами.

заботится о объекте destr

оба: destruct

Объект, возвращенный фабрикой, будет реализовывать этот "интерфейс".

...