    Указатель	на		
    базовый класс 
    Разрешено     Разрешено	 
     Разрешено 
    Базовый класс	1   Производный класс А	   Производный класс В	V 
    Данные-члены	^    Унаследованные	--       -"   1 
    !    базового класса i	данные-члены	|   данные-члены базового 
    Новые данные-члены   и производного классов 
    Новые данные-член
    Запрещено	Разрешено	
    Разрешено 
    Указатель на  производный класс А		

    Рис. 14.11. Указатель на базовый класс может ссылаться на данные-члены, 
наследуемые производным классом 

    По определению указатель типа А может ссылаться на любой из этих трех 
объектов, поскольку они связаны отношением наследования. Вы можете, к примеру, 
присвоить адрес cObject указателю на базовый класс р: 

    А *р;	// Объявить указатель на базовый класс р типа А* 
    р = ScObject; // Присвоить р адрес cObject 

    Несмотря на то что указатель р имеет тип А*, а не С*, он может ссылаться 
на объект типа С, поскольку этот класс выведен из А. Правило, возможно, будет 
понятнее вам, если вы будете думать о С, как об особом виде объекта А (так, 
золотая рыбка — особая разновидность рыб, но она все же остается рыбой). 
    Конечно, эта взаимосвязь объектов и указателей работает только в одном 
направлении. Объект типа С — особый вид объекта А, но объект типа А не является 
особым видом объектов В и С. 
    Если принцип все еще не ясен, представьте себе, что вы" — объект класса, 
выведенный из ваших родителей. Вы обладаете многими чертами ваших 
родителей, такими как цвет волос и кожи, наследованными от ваших отца и 
матери вместе с другими особенностями, наследованными от их родителей. Ваши 
родители и родители ваших родителей — часть вас, но вы не являетесь частью их. 
    Этот принцип становится особенно важным, когда в связанных отношениями 
родства классах определяются виртуальные функции.  Функции имеют точно такой же вид и 
программируются точно так же, как и обычные функции, только их объявления 
предваряются ключевым словом virtual. Например, класс А может объявить 
виртуальную функцию vf(): 

    class A { 
       public:	
          virtual void vf() ;
    }; 

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

    class В:   public A { 
     public: 
       virtual void vf(); // замещающая виртуальная функция    

    Когда в классе, подобном В, определяется виртуальная функция, имеющая 
одинаковое имя с виртуальной функцией класса-предка, такая функция называется 
замещающей. Виртуальная функция vf() в В замещает виртуальную функцию с тем же 
именем в А. 
    В классе С также можно определить замещающую виртуальную функцию: 

    class  С:    public   В   {
    public: 
       virtual void vf();
    }
    
    
    Глава 14. Объектно-ориентированное программирование 351 
