пятница, 13 августа 2010 г.

Небезопасные типы в закрытых базовых классах

Наверняка многие сталкивались с готовым кодом, который менять нельзя, хоть ты тресни. А в нем используются небозопасные типы, к примеру метод класса принимает указатель на void, а по нему не зная типа или размера нельзя корректно освободить память!
Читая Джеффа Элджера увидел интересный прием:

class UnsafeNode {
public:
  UnsafeNode(UnsafeNode * next_, void * data_);
  virtual ~UnsafeNode();
  UnsafeNode * Next();
  void * Data();
private:
  UnsafeNode * m_Next;
  void       * m_Data;
};

template < typename T>
class SafeNode : private UnsafeNode {
public:
  SafeNode(SafeNode * next_, T * data_) : UnsafeNode(next_, data_) {}
  virtual ~SafeNode() { delete( (T*)Data() ); }
  SafeNode * Next()   { return( (SafeNode*)UnsafeNode::Next() ); }
  T *  Data()         { return( (T *)UnsafeNode::Data()); } 
};

1) Потомки не видят безобразия в базовом классе, т.к. применяется закрытое наследование
2) Можно применить любой тип, т.к. шаблон
3) Коректно удалится в деструкторе, т.к. задана привязка к типу

Комментариев нет: