    Рис. 14.8 иллюстрирует представление объекта класса president в памяти. 

    Первоначальная строка, инициализированная конструктором базового класса 
    Объект president класса TBase 
    char *basep 
    char *uppercasep 
    Другие члены класса 
    "George Washington" 
    "GEORGE WASHINGTON" 
    
    Копия строки с преобразованием строчных букв в прописные, 
инициализированная конструктором производного класса

        Рис. 14.8. Представление объекта типа TDerived в памяти 


    Объект производного класса, подобный president, должен аккуратно 
освобождать все выделенные участки памяти. На рис. 14.8 объекту класса 
president принадлежит два блока памяти. Когда объект выходит из области 
видимости, его деструктор освобождает эту память и возвращает ее куче для 
последующего использования. 
    Деструктор класса TBase освобождает память, на которую ссылается член 
basep. Для простоты деструктор объявлен встраиваемым: 

    ~TBaseO { delete basep;   } 

    Аналогично, деструктор TDerived освобождает память, на которую ссылается 
член uppercasep. Опять же, объявление деструктора встраиваемым позволяет 
упростить код: 

    ~TDerivedO { delete uppercasep;   }

    В отличие от конструкторов, деструктор производного класса никогда не 
вызывает непосредственно деструктор базового класса. (Конечно, можно вызвать в 
программе деструктор как обычную функцию-член. См. главу 15.) C++ 
автоматически вызывает деструкторы, когда объекты класса выходят из области 
видимости. Например, на рис. 14.8 при выходе объекта класса president из 
области видимости C++ сначала вызывает деструктор производного класса, 
выполняющего следующий оператор: 

    delete uppercasep;	

      Затем C++ вызывает деструктор базового класса, выполняющий оператор: 

    delete basep; 

    Как видите, две строки удаляются в порядке, обратном порядку их создания. 
Самый простой способ запоминания порядка вызова конструкторов и деструкторов — 
представление иерархии базовых и производных классов в виде многоэтажного 
здания (рис. 14.9). Конструкторы базовых классов вызываются перед 
конструкторами производных классов, конструируя таким образом производные 
объекты снизу вверх, подобно тому, как небоскреб возводится ввысь от 
фундамента к крыше. Когда объект производного класса выходит из области 
видимости, его деструкторы вызываются в обратном порядке, разрушая объект по 
частям путем вызова деструкторов производных классов перед деструкторами 
базовых классов, подобно .тому, как разрушают реальное здание от крыши до фундамента.	

    Использование замещающих функций-членов 

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

    class TBase {	
    private: 
       char *sptr; }
    public: 
      TBase(const char *s) { sptr = strdup(s); } 
      ~TBase() { delete sptr; } ;
      void Display(void) { cout « sptr « '\n'; }	
    } 


    344     Часть III. Программирование на ANSI C++ 
