Существуют ли какие-либо приемы для облегчения использования шаблонов декоратора в C ++ в отношении управления памятью?
Если я использую std :: auto_ptr внутри моего декоратора, я могу создать объект в новом стиле nested, и указатели будут удалены должным образом. Однако, если я использую стиль передачи указателей для объектов, размещенных в стеке, мы неправильно удаляем эти объекты. Есть ли способ заставить это работать должным образом или применять только один стиль?
#if 0
T0 t0;
T1 t1(&t0);
T2 t2(&t1);
T3 t3(&t2);
#else
T3 t3(new T2(new T1(new T0)));
#endif
Я определил следующие простые тестовые классы.
#include <QDebug>
#include <memory>
class TI {
public:
virtual void test() = 0;
virtual ~TI() {}
};
class TD : public TI {
public:
TD(TI *ti) : _ti(ti) {}
virtual void test() { return _ti->test(); }
private:
std::auto_ptr<TI> _ti;
};
class T0 : public TI {
public:
T0() { qDebug("%s", __PRETTY_FUNCTION__); }
virtual void test() { qDebug("%s", __PRETTY_FUNCTION__); }
virtual ~T0() { qDebug("%s", __PRETTY_FUNCTION__); }
};
class T1 : public TD {
public:
T1(TI *ti) : TD(ti) { qDebug("%s", __PRETTY_FUNCTION__); }
virtual void test() { TD::test(); qDebug("%s", __PRETTY_FUNCTION__); }
virtual ~T1() { qDebug("%s", __PRETTY_FUNCTION__); }
};
class T2 : public TD {
public:
T2(TI *ti) : TD(ti) { qDebug("%s", __PRETTY_FUNCTION__); }
virtual void test() { TD::test(); qDebug("%s", __PRETTY_FUNCTION__); }
virtual ~T2() { qDebug("%s", __PRETTY_FUNCTION__); }
};
class T3 : public TD {
public:
T3(TI *ti) : TD(ti) { qDebug("%s", __PRETTY_FUNCTION__); }
virtual void test() { TD::test(); qDebug("%s", __PRETTY_FUNCTION__); }
virtual ~T3() { qDebug("%s", __PRETTY_FUNCTION__); }
};
Согласно правилам нашей компании, ваш первый вариант обязателен T0 t0; T1 t1(&t0);
, поскольку создатель (вызывающая сторона) несет ответственность за уничтожение элементов, он создал. В таком случае не имеет значения, экземпляры tater и t1 создаются в куче или в стеке.
Вторая версия T3 t3(new T2(new T1(new T0)));
звучит разумно, если можно полагаться на какую-то сборку мусора (как это делает c # или эмулирует shared_ptr). В конце идентификатор зависит от стиля кодирования и доступных структур.
Других решений пока нет …