Реализация динамического полиморфизма

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

Рубрика Программирование, компьютеры и кибернетика
Вид лекция
Язык русский
Дата добавления 02.08.2015
Размер файла 25,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Реализация динамического полиморфизма

Содержание

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

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

Адреса базовых классов

Виртуальное наследование

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

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

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

class Employee

{

private:

char name[40];

public:

Employee(char *n);

// чистая виртуальная функция

virtual void* promote()=0;

};

Для абстрактного класса не могут быть созданы объекты.

Employee s("My name")

//вызовет ошибку

Но программа может объявить указатель абстрактного класса, например

Employee *sPtr;

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

class Secretary : public Employee

{

private:

int MoreDate;

public:

Secretary(char *n):Employee(n) {}

virtual void* promote() {};

};

Secretary sec("Another Name");

Адрес объекта Secretary может быть передан в функцию, которая ожидает передачи Employee:

void fn(Employee*);

Secretary sec("Another Name");

fn(&sec);

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

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

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

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

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

Class Subclass:public Base1, private Base2

{//остальная часть определения класса

}

В определении может быть перечислено любое число базовых классов, через запятую. Ни один базовый класс не может быть прямо унаследован более одного раза. Каждый базовый класс может быть унаследован как public или как private; умолчанием является private.

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

1) Конструкторы всех виртуальных базовых классов; если их более одного, то конструкторы вызываются в порядке их наследования;

2) Конструкторы невиртуальных базовых классов в порядке их наследования;

3) Конструкторы всех компонентных классов.

#include<iostream>

struct Base1

{Base1(){cout<<"Создание Base1"<<endl;

};

struct Base2

{Base2(){cout<<"Создание Base2"<<endl;

};

struct Base3

{Base3(){cout<<"Создание Base3"<<endl;

};

struct Base4

{Base4(){cout<<"Создание Base4"<<endl;

};

struct Derived:private Base1, private Base2, private Base3

{Base4 anObject;

Derived(){};

};

void main()

{ Derived anObject;

}

Конструкторы вызовутся в порядке: Base1, Base2, Base3, Base4. Добавление в конструктор для Derived конкретных вызовов с другим порядком и повторение программы не изменит сообщения на выходе этой программы. Например:

struct Derived:private Base1, private Base2, private Base3

{Base4 anObject;

Derived(): anObject(), Base3(), Base2(), Base1() {};

};

void main()

{ Derived anObject;

}

Только изменение порядка наследования классов изменит последовательность появления сообщений на выходе программы.

Последовательность вызова деструкторов будет обратной последовательности вызовов конструкторов.

Адреса базовых классов

Основная проблема возникает в связи со способом размещения производных классов в памяти.

struct Base

{

int a;

float b;

void f1();

};

struct Derived:public Base

{int c;

} object;

Схема размещения в памяти простого производного класса:

Если Derived* передан в функцию, ожидающую получения Base*, то проблем не будет, так как их адреса совпадают.

Если наследование - множественное, то здесь ситуация может измениться. Рассмотрим пример.

struct Base1

{

int a;

float b;

void f1();

};

struct Base1

{

int с;

float в;

void f2();

};

struct Derived:public Base1, public Base2

{int e;

} object;

Схема размещения в памяти класса Derived:

Если Derived* передан в функцию, ожидающую Base1*, то проблем не будет, если же Derived* передан в функцию, ожидающую Base2*, то так как их адресы не совпадают, возникает ошибка. Чтобы исправить этот адрес, необходимо прибавить к адресу Derived::object смещение Base2 Derived, таким образом, чтобы результат указывал на ту часть, которая относится к Base2. Такая же коррекция должна выполняться для каждого случая приведения типа указателей из Derived* в Base2*, включая и скрытый указатель this, передаваемый компонентным функциям Base2.

По тем же причинам С++ также должен выполнить коррекцию и при обратном приведении типа из Base2* в derived*

Виртуальное наследование

Рассмотрим пример.

struct Base

{

int object;

};

struct FirstBase : public Base

{

int a;

};

struct SecondBase : public Base

{

float b;

};

class Derived : public FirstBase, public SecondBase

{

long dObject;

};

Схема размещения в памяти класса Derived:

Чтобы позволить наследование в таких случаях одной и той же копии Base, в C++ необходимо включить в команду наследования ключевое слово virtual.

struct Base

{

int object;

};

struct FirstBase : virtual public Base

{

int a;

};

struct SecondBase : virtual public Base

{

float b;

};

class Derived : virtual public FirstBase, virtual public SecondBase

{

long dObject;

};

Схема размещения в памяти класса Derived в этом случае:

Теперь осталась одна копия объекта Base.

Правило isA()

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

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

Пример.

#include <iostream>

using namespace std;

struct Base

{

enum ClassType{BASE,SUBCLASS};

virtual ClassType isA()

{

return BASE;

}

};

struct SubClass:public Base

{

virtual ClassType isA()

{

return SUBCLASS;

}

};

void print(Base& obj)

{

if(obj.isA()==Base::BASE) cout<<"Это объект ,fpjdjuj rkfccf\n";

else if (obj.isA()==Base::SUBCLASS)

cout<<"Это объект подкласса\n";

else cout<<"Это неизвестный тип объекта\n";

}

void fn(Base& obj)

{

print(obj);

}

int main()

{

Base aBaseClass;

SubClass aSubClass;

fn(aBaseClass);

fn(aSubClass);

return 0;

}

Размещено на Allbest.ru

...

Подобные документы

  • Цели объектно-ориентированного программирования, абстрактные классы и адреса базовых классов, множественное и виртуальное наследование. Инициализация элементов производного класса, программный вызов конструкторов базового и производного классов.

    реферат [21,8 K], добавлен 31.10.2011

  • Переопределение метода внутри одного класса. Сущность перегрузки унаследованного метода. Области применения абстрактного класса. Перегрузка унарных и бинарных операций. Области видимости локальных и глобальных переменных. Способы обращения к ним.

    презентация [81,2 K], добавлен 09.12.2013

  • Построение абстрактной модели. Структура базового класса System_Term: формальное описание класса, структура данных и функций, инструкция программиста и пользователя. Структура базовых классов mobile, Home, TV, Internet, их составные части и функционал.

    курсовая работа [1,2 M], добавлен 20.06.2014

  • Изображение класса на диаграмме UML. Инкапсуляция как средство защиты его внутренних объектов. Использование принципа полиморфизма для реализации механизма интерфейсов. Создание новых классов путем наследования. Ассоциация как вид отношений между ними.

    лекция [516,6 K], добавлен 03.12.2013

  • Понятие перегрузки (доопределения) операций и её разновидности. Пример соответствующей программы перегрузки, понятие полиморфизма и правила isA. Использование классов операторов в программах языка С++, конструкций операторов и производных классов.

    реферат [19,9 K], добавлен 30.10.2011

  • Иерархия и типы классов в программе, особенности обеспечения наследования. Наследование по принципу подчиненности. Включение в другие классы или делегирование. Понятие изолированных классов. Конструкторы и деструкторы. Иерархия классов NET Framework.

    презентация [91,8 K], добавлен 09.12.2013

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

    курсовая работа [630,0 K], добавлен 19.03.2012

  • Разработка интерфейса для объединения в структуру данных множества объектов различных классов (абстрактный базовый класс TObject). Создание таблиц (коллекций) объектов с помощью механизма объектно-ориентированного программирования - полиморфизма.

    курсовая работа [175,7 K], добавлен 06.08.2013

  • Понятия шаблонов функции и класса, правила описания на языке С++. Разработка и отлаживание в среде программирования программ, содержащих шаблоны функций и классов. Шаблон функции square, возвращающей квадрат переменной. Создание шаблона класса массива.

    лабораторная работа [162,6 K], добавлен 25.05.2013

  • Основные приемы работы с классами и объектами. Перегрузка функций и операторов. Массивы объектов. Реализация одиночного наследования. Множественное наследование. Виртуальные функции. Шаблоны: понятие и функциональные особенности, свойства и применение.

    методичка [1,1 M], добавлен 16.04.2012

  • Освоение методики проектирования программных комплексов на базе объектно-ориентированного программирования. Описание понятий класс, конструктор и деструктор, наследование простое и множественное. Реализация объектной модели на языке программирования с++.

    курсовая работа [468,5 K], добавлен 11.12.2011

  • Механизм классов в C++. Инициализация внутреннего объекта с помощью конструктора. Управление доступом к классу. Защищенные члены класса. Графические средства компилятора Borland C 3.1. Библиотека стандартных шаблонов. Реализация и использование класса.

    курсовая работа [2,7 M], добавлен 16.05.2012

  • Основные понятия объектно-ориентированного программирования в PHP5. Структурный и объектно-ориентированный подход. Класс как абстрактный тип. Реализация класса. Конструкторы и деструкторы. Функция l_visited_style изменение стиля посещенных ссылок.

    курсовая работа [433,2 K], добавлен 13.06.2008

  • Разработка иерархии классов, содержащей не менее трех уровней. Определение базовых и производных классов. Анализ технического задания. Проектирование структуры программы и базовых алгоритмов. Программная реализация разработанной структуры и алгоритмов.

    курсовая работа [34,9 K], добавлен 11.01.2011

  • Объявление объекта, присвоение ему числового значения. Инкапсуляция и спецификаторы доступа. Функции для работы с методами и классами. Вызов конструктора из внешнего кода. Спецификаторы доступа при наследовании. Объявление закрытого деструктора в классе.

    презентация [112,3 K], добавлен 21.06.2014

  • Классы, объекты и объектные ссылки. Особенности статических методов. Конструкторы, специальные переменные, наследование. Создание объектов внутренних классов. Соглашения об именовании. Некоторые методы класса Object. Абстрактные классы и атрибуты.

    лекция [130,6 K], добавлен 21.06.2014

  • Причины возникновения объектно-ориентированного программирования. Графическое представление классов; их отличия от других абстрактных типов данных. Типы абстракции, используемые при построении объекта. Сущность инкапсуляции, наследования и полиморфизма.

    контрольная работа [222,1 K], добавлен 04.06.2014

  • Распределение виртуальной памяти. Страничная и сегментная организации виртуальной памяти. Сегментно-страничная организация виртуальной памяти. Преобразование виртуального адреса в физический. Упрощение адресации памяти клиентским программным обеспечением.

    курсовая работа [440,7 K], добавлен 04.03.2014

  • Виды коллекций-классов, реализующих интерфейс Collection. Основные классы пакета java.util и работа с системным временем (Класс java.util.Date), файлами и потоками ввода/вывода, обработка строки (объекты класса String). Спецификация класса Statistics.

    методичка [185,8 K], добавлен 30.06.2009

  • Описание классов данных. Основное меню программы. Добавление и удаление объектов. Вывод устройств хранения в указанном ПК. Устройство хранения, класс ноутбук, класс жёсткий диск, класс персональный компьютер, класс планшет и класс Flash-память.

    курсовая работа [1,8 M], добавлен 30.03.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.