1.4.6 Множественные реализации.

   


Назад  |  Вперёд

Основные средства, поддерживающие объектно-ориентированное программирование, а именно: производные классы и виртуальные функции,- можно использовать и для поддержки абстракции данных, если допустить несколько реализаций одного типа. Вернемся к примеру со стеком:

                template < class T >
                class stack
                {
                    public:
                    virtual void push ( T ) = 0; // чистая виртуальная функция
                    virtual T pop () = 0;      // чистая виртуальная функция
                };

Обозначение =0 показывает, что для виртуальной функции не требуется никакого определения, а класс stack является абстрактным, т.е. он может использоваться только как базовый класс. Поэтому стеки можно использовать, но не создавать:

              class cat { /* ... */ };
              stack < cat > s;    // ошибка: стек - абстрактный класс

              void some_function ( stack <cat> & s, cat kitty ) // нормально
              {
                s.push ( kitty );
                cat c2 = s.pop ();
                // ...
              }

Поскольку интерфейс стека ничего не сообщает о его представлении, от пользователей стека полностью скрыты детали его реализации.

Можно предложить несколько различных реализаций стека. Например, стек может быть массивом:

             template < class T >
             class astack : public stack < T >
             {
             // истинное представление объекта типа стек
             // в данном случае - это массив
             // ...
             public:
               astack ( int size );
               ~astack ();

               void push ( T );
               T pop ();
             };

Можно реализовать стек как связанный список:

                template < class T >
                class lstack : public stack < T >
                {
                // ...
                };

Теперь можно создавать и использовать стеки:

             void g ()
             {
               lstack < cat > s1 ( 100 );
               astack < cat > s2 ( 100 );

               cat Ginger;
               cat Snowball;

               some_function ( s1, Ginger );
               some_function ( s2, Snowball );
             }

О том, как представлять стеки разных видов, должен беспокоиться только тот, кто их создает (т.е. функция g()), а пользователь стека (т.е. автор функции some_function()) полностью огражден от деталей их реализации. Платой за подобную гибкость является то, что все операции над стеками должны быть виртуальными функциями.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.