Бьерн Страуструп - Язык программирования С++. Вступление, глава 1
Страница 38. Проверка типа


 

1.5.2  Проверка типа

    Необходимость контроля типа при обращениях к виртуальным функциям
может оказаться определенным ограничением для разработчиков библиотек.
Например, хорошо бы предоставить пользователю класс "стек чего-угодно".
Непосредственно в С++ это сделать нельзя. Однако, используя шаблоны типа и
наследование, можно приблизиться к той эффективности и простоте
проектирования и использования библиотек, которые свойственны языкам с
динамическим контролем типов. К таким языкам относится, например, язык
Smalltalk, на котором можно описать "стек чего-угодно".  Рассмотрим
определение стека с помощью шаблона типа:

            template < class T > class stack
            {
               T * p;
               int sz;
            public:
               stack ( int );
               ~stack ();

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

    Не ослабляя статического контроля типов, можно использовать такой стек
для хранения указателей на объекты типа plane (самолет):

        stack < plane * > cs ( 200 );

        void f ()
        {
           cs.push ( new Saab900 );   // Ошибка при трансляции :
                                      // требуется plane*, а передан car*
           cs.push ( new Saab37B );
                                      // прекрасно: Saab 37B - на самом
                                      // деле самолет, т.е. типа plane
           cs.pop () -> takeoff ();
           cs.pop () -> takeoff ();
         }

    Если статического контроля типов нет, приведенная выше ошибка
обнаружится только при выполнении программы:

         // пример  динамическое контроля типа
         // вместо статического; это не С++
         Stack s; // стек может хранить указатели на объекты
                  // произвольного типа
          void f ()
          {
             s.push ( new Saab900 );
             s.push ( new Saab37B );
             s.pop () -> takeoff ();  // прекрасно: Saab 37B - самолет
             cs.pop () -> takeoff ();  // динамическая ошибка:
                                   // машина не может взлететь
          }

    Для способа определения, допустима ли операция над объектом, обычно
требуется больше дополнительных расходов, чем для механизма вызова
виртуальных функций в С++.

    Рассчитывая на статический контроль типов и вызов виртуальных функций,
мы приходим к иному стилю программирования, чем надеясь только на
динамический контроль типов. Класс в С++ задает строго определенный
интерфейс для множества объектов этого и любого производного класса, тогда
как в Smalltalk класс задает только минимально необходимое число операций,
и пользователь вправе применять незаданные в классе операции. Иными
словами, класс в С++ содержит точное описание операций, и пользователю
гарантируется, что только эти операции транслятор сочтет допустимыми.

 
« Предыдущая статья   Следующая статья »