Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Конструкторы и деструкторы при наследовании




Виртуальный базовый класс

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

Полиморфизм и позднее связывание

Термины « полиморфизм» и «позднее (динамическое) связывание» обычно применяются, когда говорят о механизмах наследования и виртуальных функций языка С++.

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

по-разному определяться несколькими производными классами. Другими словами, это способность указателей (или ссылок) на базовый класс “принимать различные формы, характер или стиль” (определение слова полиморфный у Вебстера) в контексте наследования и виртуальных механизмов. Термин «позднее связывание» относится к тому обстоятельству, что компилятор не может определить заранее, какая функция должна вызываться на самом деле, если обращение к виртуальной функции использует указатель или ссылку на базовый класс. Хотя переменная и определяется как указатель на базовый класс, она в действительности может указывать на объект производного класса. Эта особенность виртуального механизма приводит к тому, что адрес функции может быть найден только во время выполнения программы.

 

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

Пример.

 

Class А

{

protected:

public:

};

Class В

{

protected:

public:

};

Class С: рublic А, рublic В

 

{

};

 

 

При множественном наследовании производный класс может наследовать более одного экземпляра базового класса. В результате может возникнуть неоднозначность элементов. Чтобы производный класс наследовал только один экземпляр некоторого базового класса, нужно этот базовый класс объявить виртуальным. Для этого при спецификации производного класса перед именем базового класса нужно поставить ключевое слово virtual. Например, башня может состоять из конической и цилиндрической частей. У обоих есть такие общие элементы-данные, как объем, вес, полная поверхность. Эти общие элементы можно выделить в базовый класс class fiqure, от которого class conus и class cilindr являются производными. В свою очередь, class cilindr и class conus являются базовыми для класса class tower(башня). Имеет место множественное наследование. Чтобы производный class tower наследовал только один экземпляр базового класса fiqure, следует class fiqure объявить виртуальным при описании классов conus и cilindr.

class fiqure

[

protectrd:

};

class conus:public virtual fiqure

{

protectrd:

};

class cilindr: public virtual fiqure

{

protectrd:

};

class tower: public conus, public cilindr

{

};

 

 

 

Следующий список показывает последовательность шагов при конструировании производного класса:

1) Вызывается конструктор базового класса.

2) Вызывается конструктор тех элементов, которые являются объектами какого-либо класса, в том порядке, в котором производный класс их объявляет.

3) Исполняется тело конструктора производного класса.

Деструкция производного класса выполняется в порядке, обратном конструированию:

1) Вызывается деструктор производного класса.

2) Вызываются деструкторы элементов, являющихся объектами классов.

3) Вызывается деструктор базового класса.

 

22.6 Абстрактные классы и чистые виртуальные функции

 

Абстрактным является класс, в котором есть хотя бы одна чистая виртуальная функция. Напомним ее вид:

virtual тип_результата имя_функции()=0

Она может рассматриваться как встроенная (inline-функция), тело которой определено как =0 (чистый спецификатор). Чистая виртуальная переопределяется в производных классах. Другими словами, в абстрактном классе только объявляются функции с определенными именами, а конкретное содержание того, что будут делать эти функции, будет определено в производных классах. Ясно, что из-за этого абстрактный класс может использоваться только в качестве базового для других классов. К абстрактным классам применимы следующие правила:

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

2 Абстрактный класс нельзя использовать в явном преобразовании.

3 Нельзя определить объект абстрактного класса (глобальную/локальную переменную или элемент данных).

4 Можно определять указатель или ссылку на абстрактный класс.

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

Рассмотрим пример. У плоской фигуры есть общие элементы данных: периметр(perimetr) и площадь(plo). Есть конкретные плоские фигуры: прямоугольник (rectangle) и круг (crug). Для каждой из этих фигур имеются свои элементы-данные и по-разному вычисляются периметр (длина окружности для круга) и площадь. При программировании удобно, чтобы члены функции ввода/вывода данных, а также функции вычисления периметра и площади имели одинаковые имена как при работе с прямоугольником, так и при вычислении параметров круга. Сделаем class fiqure базовым. В нем опишем чистые виртуальные функции для ввода, вывода данных, вычисления периметра и вычисления площади. Определим два производных класса: class crug и class rectangle. В них будут переопределены чистые виртуальные функции.

 

#include<stdio.h>

#include<math.h>

class fiqure

{

protectrd:

float perimeter, plo;

public:

virtual void input()=0;//Ввод данных

virtual void output()=0;//Вывод результатов

virtual void l()=0;//Вычисление периметра

virtual void s()=0;// Вычисление площади

}

class crug: public fiqure

{

float R; //Радиус

public:

void input()//virtual можно не писать

{

puts(“Введите радиус”)

scanf(“%f, &R);

}

void output()

printf(“Для круга длина окружности (perimetr)=%f, площадь=%f\n”, perimetr, plo);

}

void l()

{

perimeter=2*M_PI*R;

}

void s()

{

plo =M_PI*R*R

}

};

class reet: public fiqure

{

float a,b;//ширина и длина

public:

void input()

{

puts(“Введите а и в”);

scanf(“%f%f, &a, &b);

}

void output()

{

printf(“Для прямоугольника периметр=%f площадь =%f \n”perimetr, plo);

}

void l()

{

perimetr =2*(a+b);

}

void s()

{

plo =a*b;

}

};

void main()

{

fiqure*p=new crug;/*В указатель р на базовый класс заносится адрес, выделенный под объект производного класса crug*/

p→input();

p→l();

p→s();

p→output();/*Последовательно вызываются функции класса crug*/

p=new rectangle;

p→input();

p→l();

p→s();

p→output();

}

После занесения в указатель р адреса для объекта класса rectangle происходит вызов соответствующих виртуальных функций класса rectangle.

 




Поделиться с друзьями:


Дата добавления: 2015-06-27; Просмотров: 870; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.03 сек.