Листинг 6: Множественное наследование




 

#include <iostream>

using namespace std;

 

class basel {

protected:

int x;

public:

void showx() { cout << x << "\n"; }

};

 

 

class base2 {

protected:

int y;

public:

void showy() {cout << y << "\n";}

};

// Множественное наследование.

class derived: public basel, public base2 {

public:

void set(int i, int j) { x=i; y=j; }

};

 

int main()

{

derived ob;

ob.set(10, 20); // Эта функция принадлежит классу derived,

ob.showx(); // Эта функция принадлежит классу basel.

ob.showy(); // Эта функция принадлежит классу base2.

return 0;

}

 

Результат:

 

Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется приведенными ниже правилами.

· Если в конструкторе производного класса явный вызов конструктора базового класса отсутствует, автоматически вызывается конструктор базового класса по умолчанию (то есть тот, который можно вызвать без параметров).

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

· В случае нескольких базовых классов их конструкторы вызываются в порядке объявления.

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

· образом вызван в конструкторе производного класса в списке инициализации

Вызов функций базового класса предпочтительнее копирования фрагментов кода из функций базового класса в функции производного.

Деструкторы не наследуются.

· Если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов.

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

· Для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов: сначала вызывается деструктор класса, затем — деструкторы элементов класса, а потом деструктор базового класса.

Полиморфизм

Языки объектно-ориентированного программирования поддерживают полиморфизм, который характеризуется фразой “один интерфейс, несколько методов”.

Полиморфизм — это атрибут, позволяющий с помощью одного интерфейса управлять доступом к целому классу методов. Конкретный выбор определяется возникшей ситуацией.

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

Этот принцип распространяется и на программирование. Например, допустим, что в программе определены три разных типа стека. Один стек состоит из целых чисел, другой — из символов, а третий — из чисел с плавающей точкой. Благодаря полиморфизму программисту достаточно определить функции push() и рор(), которые можно применять к любому типу стека. В программе необходимо создать три разные версии этих функций для каждой разновидности стека, но имена этих функций должны быть одинаковыми. Компилятор автоматически выберет правильную функцию, основываясь на информации о типе данных, хранящихся в стеке. Таким образом, функции push() и pop () — интерфейс стека — одинаковы, независимо от типа стека. Конкретные варианты этих функций определяют конкретные реализации (методы) для каждого типа данных.

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

Язык C++ обеспечивает как статический, так и динамический полиморфизм.

Статический полиморфизм достигается с помощью перегрузки функций и операторов. Динамический полиморфизм реализуется на основе наследования и виртуальных функций.

Виртуальные методы

Виртуальная функция — это функция-член, объявленная в базовом классе и переопределенная в производном.

Производный класс переопределяет эту функцию, приспосабливая ее для своих нужд. По существу, виртуальная функция реализует принцип “один интерфейс, несколько методов”, лежащий в основе полиморфизма. Виртуальная функция в базовом классе определяет вид интерфейса, т.е. способ вызова этой функции. Каждое переопределение виртуальной функции в производном классе реализует операции, присущие лишь данному классу. Иначе говоря, переопределение виртуальной функции создает конкретный метод. Таким образом, можно создать функцию, параметром которой является указатель на абстрактный класс. На место этого параметра при выполнении программы может передаваться указатель на объект любого производного класса. Это позволяет создавать полиморфные функции, работающие с объектом любого типа в пределах одной иерархии.

Синтаксис:

virtual void f(int)

Листинг 7: Полиморфизм

 

#include <iostream>

using namespace std;

 

class base {

public:

virtual void vfunc() {

cout << " Функция vfunc() из класса base.\n";

}

};

class derivedl: public base {

public:

void vfunc() {

cout << " Функция vfunc() из класса derivedl.\n";

}

};

class derived2: public base {

public:

void vfunc() {

cout << " Функция vfunc() из класса derived2.\n";

}

};

 

void f(base &r)

{

r.vfunc();

}

 

int main()

{

system("chcp 65001");

base b;

derivedl d1;

derived2 d2;

f(b); // Функции f() передается объект класса base,

f(d1); // Функции f() передается объект класса derivedl.

f(d2); // Функции f() передается объект класса derived2.

return 0;

}

 

Правила описания и использования виртуальных методов:

· Если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным, а с отличающимся набором параметров — обычным.

· Виртуальные методы наследуются, то есть переопределять их в производном классе требуется только при необходимости задать отличающиеся действия. Права доступа при переопределении изменить нельзя.

· Если виртуальный метод переопределен в производном классе, объекты этого класса могут получить доступ к методу базового класса с помощью операции доступа к области видимости.

· Виртуальный метод не может объявляться с модификатором static, но может быть объявлен как дружественный.

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

Чисто виртуальный метод содержит признак == 0 вместо тела, например,

virtual void f(int) = 0;

Чисто виртуальный метод должен переопределяться в производном классе (возможно, опять как чисто виртуальный).

Абстрактные классы

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

Особенности:

· абстрактный класс нельзя использовать при явном приведении типов, для описания типа параметра и типа, возвращаемого функцией значения;

· допускается объявлять указатели и ссылки на абстрактный класс, если при инициализации не требуется создавать временный объект;

· если класс, производный от абстрактного, не определяет все чисто виртуальные функции, он также является абстрактным.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-07-02 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: