Бьерн Страуструп.
Язык программирования С++
361
virtual void remove(T* p)
{ lock(); rep->remove(p); unlock(); }
virtual int is_member(T* p)
{
return
rep->is_member(p);
}
virtual T* first() { return rep->first(); }
virtual T* next() { return rep->next(); }
//
...
};
Писать функции-переходники для всего интерфейса утомительно (а значит могут появляться ошибки),
но не трудно и это не ухудшает характеристик программы.
Заметим, что не все функции из set следует блокировать. Как показывает опыт автора, типичный
случай, когда операции до и после обращения к объекту надо выполнять не для всех, а только для
некоторых функций-членов. Блокировка всех операций, как это делается в мониторах некоторых
операционных систем, является избыточной и может существенно ухудшить параллельный режим
выполнения.
Переопределив все функции интерфейса в управляющем классе, мы получили по сравнению с
приемом перегрузки операции ->, то преимущество, что теперь можно строить производные от
set_controller классы. К сожалению, мы можем потерять и некоторые достоинства управляющего класса,
если к производным классам будут добавляться члены, представляющие данные. Можно сказать, что
программный объем, который разделяется между управляемыми классами уменьшается по мере роста
программного объема управляющего класса.
Достарыңызбен бөлісу: