В качестве более конкретного примера рассмотрим короткую программу, которая определяет базовый класс B_class и производный класс D_class. В этой программе простая иерархия классов используется для хранения имен авторов и названий их книг.

// Использование указателей на базовый класс для доступа к объектам производных классов.

#include

#include

using namespace std;

class B_class {

   char author[80];

  public:

   void put_author(char *s) { strcpy(author, s); }

   void show_author() { cout << author << "\n"; }

};

class D_class : public B_class {

  char title [80];

 public:

  void put_title(char *num) { strcpy(title, num);}

  void show_title() {

   cout << "Название: ";

   cout << title << "\n";

  }

};

int main()

{

 B_class *p;

 B_class B_ob;

 D_class *dp;

 D_class D_ob;

 p = &B_ob; // адрес объекта базового класса

 // Доступ к классу B_class через указатель.

 p->put_author("Эмиль Золя");

 // Доступ к классу D_class через "базовый" указатель.

 р = &D_ob;

 p->put_author("Уильям Шекспир");

 // Покажем, что каждый автор относится к  соответствующему объекту.

 B_ob.show_author();

 D_ob.show_author();

 cout << "\n";

 /* Поскольку функции put_title() и show_title() не являются частью базового класса, они недоступны через "базовый" указатель р, и поэтому к ним нужно обращаться либо непосредственно, либо, как показано здесь, через указатель на производный тип.

 */

 dp = &D_ob;

 dp->put_title("Буря");

 p->show_author(); // Здесь можно использовать либо указатель р, либо указатель dp.

 dp->show_title();

 return 0;

}

При выполнении эта программа отображает следующие результаты.

Эмиль Золя

Уильям Шекспир

Уильям Шекспир

Название: Буря

В этом примере указатель р определяется как указатель на класс B_class. Но он может также ссылаться на объект производного класса D_class, причем его можно использовать для доступа только к тем элементам производного класса, которые унаследованы от базового. Однако следует помнить, что через "базовый" указатель невозможно получить доступ к тем членам, которые специфичны для производного класса. Вот почему к функции show_title() обращение реализуется с помощью указателя dp, который является указателем на производный класс.

Если вам нужно с помощью указателя на базовый класс получить доступ к элементам, определенным производным классом, необходимо привести этот указатель к типу указателя на производный тип. Например, при выполнении этой строки кода действительно будет вызвана функция show_title() объекта D_ob:

((D_class *)р)->show_title();

Внешний набор круглых скобок используется для связи операции приведения типа с указателем р, а не с типом, возвращаемым функцией show_title(). Несмотря на то что в использовании такой операции формально нет ничего некорректного, этого по возможности следует избегать, поскольку подобные приемы попросту вносят в код программы путаницу. (На самом деле большинство С++-программистов считают такой стиль программирования неудачным.)

Кроме того, необходимо понимать, что хотя "базовый" указатель можно использовать для доступа к объектам любого производного типа, обратное утверждение неверно. Другими словами, используя указатель на производный класс, нельзя получить доступ к объекту базового типа.

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги