Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ЯП_Си++_03_Наследование

.pdf
Скачиваний:
15
Добавлен:
12.02.2015
Размер:
289.86 Кб
Скачать

Примеры необходимости позднего (динамического) связывания

1.Функция, параметром которой является указатель на объект базового класса. На его место во время выполнения программы может быть передан указатель на объект любого производного класса.

2.Массив, элементами которого являются указатели на объекты любого производного класса. С элементами массива требуется работать единообразно.

11

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

1. Наследуется ли виртуальность метода?

«Да», если в производном классе метод переопределен с тем же именем и набором параметров.

2. Наследуется ли виртуальный метод?

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

3. Может быть static? «Нет».

12

/=============time.h============ class Time{

virtual void printTime();

};

ФОРМАЛЬНЫЙ тип объекта

//==========main.cpp============= //описание указателя на базовый класс

Time *pt;

//указатель ссылается на объект производного класса pt = new TimeDate();

//будет вызван метод класса TimeDate pt->printTime();

ФАКТИЧЕСКИЙ тип объекта

Полиморфный объект – определен через указатель и содержит виртуальные методы – поведение зависит от фактического типа.

13

Таблица виртуальных методов

 

замедление

Создается для каждого класса, содержащего хотя бы один виртуальный метод.

Что делать виртуальным?

1. Деструкторы.

Чтобы гарантировать вызов деструктора, соот-

//time.h

ветствующего ФАКТИЧЕСКОМУ типу объекта.

class Time{

 

 

 

virtual ~Time();//деструктор

};

 

 

Теперь виртуальными будут деструкторы и всех производных классов (хотя они будут иметь другие имена)!

2. Методы, которые планируется переопределить в производных классах.

14

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

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

virtual void printTime() = 0;

virtual void printTime() {};//в чем разница?

Абстрактный класс – содержит хотя бы один чисто виртуальный метод.

-используется для представления общих понятий, которые необходимо конкретизировать в производных классах;

-вызов чисто виртуального метода приводит к ошибке → объект абстрактного класса создавать НЕЛЬЗЯ! Но указатель МОЖНО!

15

Чисто виртуальный метод

 

Чисто виртуальный метод

Shape

show()

show()

 

 

TwoDimShape

ThreeDimShape

Круг

 

 

 

 

 

 

 

Треугольник

 

Квадрат

 

 

 

 

 

Шар

 

 

 

 

 

Куб

Shape* massiv[3];

 

 

Пирамида

 

massiv[0] = new

Круг();

 

 

 

 

 

 

 

massiv[1]

=

new

Пирамида();

 

 

Метод show()получил

massiv[2]

=

new

Квадрат();

 

 

реализацию

for(int i=0;i<3;i++){ massiv[i]->show();

}

16

//----------------time.h---------------------

class Time{

friend void newYear(Time &);

protected:

//час

int hour;

int

minute;

//минута

int

second;

//секунда

char* stime;

//строка-комментарий

static int count; //общее число объектов класса public:

Time(int = 0, int = 0, int = 0, char* = 0); Time(const Time&);

explicit Time(char *); virtual ~Time();

int getHour() const {return hour;}

int getMinute() const {return minute;} int getSecond() const {return second;} void setTime(int, int, int);

virtual void printTime();

17

Time& later(Time&);

static void incCount(){count++;} static int getCount(){return count;}

Time& operator ++ (); bool operator > (Time&);

Time& operator = (const Time&); operator int();

int& operator [] (int);

};

18

//==============производный класс===============

class TimeDate: public Time{ private:

int day; int month; int year;

public:

TimeDate(int = 1, int = 1, int = 1); TimeDate(int, int, int, int, int, int, char *); TimeDate(TimeDate &t);

TimeDate& operator = (const TimeDate &); void printTime();

};

19

Time* massiv[4];

massiv[0] = new Time(10,0,0,"завтрак"); massiv[1] = new Time(20,0,0,"ужин");

massiv[2] = new TimeDate(00,00,00,1,1,2011,"новый год"); massiv[3] = new TimeDate(0,0,0,2,1,2011,"сессия");

for(int i=0;i<4;i++){ massiv[i]->printTime();

}

massiv[0]->~Time(); massiv[1]->~Time(); ((TimeDate*)massiv[2])->~TimeDate(); ((TimeDate*)massiv[3])->~TimeDate();

//но ведь деструкторы виртуальные – можно ли в цикле? ДА!

for(int i=0;i<4;i++){ massiv[i]->~Time();

}

20