18.3.1. Наследование и композиция

18.3.1. Наследование и композиция

Реализация класса 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;

}

* Решая, следует ли использовать при проектировании класса с отношением "СОДЕРЖИТ" композицию или закрытое наследование, можно руководствоваться такими соображениями: если мы хотим заместить какие-либо виртуальные функции базового класса, то должны закрыто наследовать ему;

* если мы хотим разрешить нашему классу ссылаться на класс из иерархии типов, то должны использовать композицию по ссылке (мы подробно расскажем о ней в разделе 18.3.4);

* если, как в случае с классом PeekbackStack, мы хотим воспользоваться готовой реализацией, то композиция по значению предпочтительнее наследования. Если требуется отложенное выделение памяти для объекта, то следует выбрать композицию по ссылке (с помощью указателя).