Наследование и композиция
Реализация класса PeekbackStack с помощью закрытого наследования от IntArray работает, но необходимо ли это? Помогло ли нам наследование в данном случае? Нет.
Открытое наследование – это мощный механизм для поддержки отношения “ЯВЛЯЕТСЯ”. Однако реализация PeekbackStack по отношению к IntArray – пример отношения “СОДЕРЖИТ”. Класс PeekbackStack содержит класс IntArray как часть своей реализации. Отношение “СОДЕРЖИТ”, как правило, лучше поддерживается с помощью композиции, а не наследования. Для ее реализации надо один класс сделать членом другого. В нашем случае объект IntArray делается членом PeekbackStack. Вот реализация PeekbackStack на основе композиции:
class PeekbackStack {
private:
const int static bos = -1;
public:
explicit PeekbackStack( int size ) :
stack( size ), _top( bos ) {}
bool empty() const { return _top == bos; }
bool full() const { return _top == size()-1; }
int top() const { return _top; }
int pop() {
if ( empty() )
/* обработать ошибку */ ;
return stack[ _top-- ];
}
void push( int value ) {
if ( full() )
/* обработать ошибку */ ;
stack[ ++_top ] = value;
}
bool peekback( int index, int &value ) const;
private:
int _top;
IntArray stack;
};
inline bool
PeekbackStack::
peekback( int index, int &value ) const
{
if ( empty() )
/* обработать ошибку */ ;
if ( index < 0 || index > _top )
{
value = stack[ _top ];
return false;
}
value = stack[ index ];
return true;
}
Решая, следует ли использовать при проектировании класса с отношением “СОДЕРЖИТ” композицию или закрытое наследование, можно руководствоваться такими соображениями: