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

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

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

3. Наследование

Базовый класс существующий класс

Отношение «ЯВЛЯЕТСЯ»

Производный класс новый класс

 

 

 

3.1. Параметры доступа

 

По умолчанию

Спецификатор (статус) доступа

 

 

 

 

 

 

Элементы базового

 

В производном

Для клиентов

 

класса

 

 

классе

классов

 

private-элементы

 

недоступны

недоступны

 

protected-элементы

 

доступны

недоступны

 

public-элементы

 

 

доступны

доступны

1

Ключ доступа

class имя : [private | protected | public] базовый_класс{

};

тело класса

По умолчанию

 

private – закрытое наследование protected – защищенное наследование public – открытое наследование

Статус доступа

private-

 

 

protected -

public -

элементов

наследование

 

 

наследование

наследование

базового класса

Статус доступа элементов производного класса

 

 

 

 

 

private

private

private

 

 

private

protected

private

 

 

protected

protected

public

private

 

 

protected

public

 

 

2

 

 

Конструктор копирования
Еще один конструктор с 7-ю параметрами Конструктор по умолчанию

3.2. Простое наследование (один базовый класс)

Конструкторы

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

//производный класс от базового класса Time 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(const TimeDate &);

//операции

TimeDate& operator = (const TimeDate &); //прочие методы

void printTime();

3

};

time.cpp

 

//----------------

 

//----------------

конструкторы-----------------

Явный вызов конструктора

Конструктор по умолчанию

базового класса отсутствует

TimeDate::TimeDate(int d, int m, int y){ day = d; month = m; year = y;

}

//автоматически вызывается конструктор по умолчанию //базового класса

Конструктор базового класса требует указания параметров

TimeDate::TimeDate(int h, int m, int s, int d, int mm, int y, char *str): Time(h,m,s,str){

day = d; month = mm; year = y;

}

Конструктор базового класса явно 4 вызван в списке инициализации

Конструктор копирования

Конструктор копирования базового класса

 

вызывается в списке инициализации

TimeDate::TimeDate(const TimeDate &td): Time(td) { day = td.day; month = td.month; year = td.year;

}

Конструктор копирования класса Time вызван с параметром типа TimeDate&, а не Time&

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

2.В производном классе явно не вызывается конструктор базового класса → автоматически вызывается конструктор по умолчанию базового класса.

3.Конструктор базового класса требует указания параметров → его надо вызвать явно в списке инициализации.

5

 

Операция присваивания

//-------------

операция присваивания-------------------

TimeDate &TimeDate::operator = (const TimeDate &td){ //проверка на самоприсваивание

if (&td == this) return *this;//сравнение адресов

Time::operator = (td);

//явный вызов функции-операции из базового класса

day = td.day; month = td.month; year = td.year;

return *this;

 

}

 

 

1.

Сокращение объема кода.

Можно интерпретировать как

имя функции-операции

2.

Упрощение модификации.

 

3.Меньше ошибок.

1.Операция присваивания не наследуются → производный класс должен иметь собственную операцию присваивания.

6

Деструкторы

Базовый класс

Конструкторы

Деструкторы

 

 

 

Производный класс

Порядок вызовов конструкторов / деструкторов

1.Деструктор не наследуются → если необходимо (есть поля-указатели и т.п.) производный класс должен иметь собственный явно написанный деструктор.

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

3.В деструкторе производного класса (как написанного явно, так и созданного автоматически) деструктор базового класса вызывается автоматически.

7

Прочие методы

В классе TimeDate описан метод printTime, который переопределяет метод с тем же именем в классе Time.

↓↓

Производный класс может не только дополнять, но и корректировать поведение базового класса!

//------------------прочие методы---------------------------

void TimeDate::printTime(){

printf("%2.2i:%2.2i:%2.2i - %2.2i.%2.2i.%4.4i - %s\n", hour,minute,second,day,month,year,stime);

//если в классе Time private заменить на protected, то //можно получить доступ к полям hour,minute,second,stime

//можно требуемые поля переопределить в TimeDate //public: Time::hour;

}

8

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

Time *pt;//указатель на объект

Time t;//объект

Эффективнее – указатель на базовый класс можно «связать» с объектом любого производного класса!

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

Time *pt;

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

9

Вызов методов происходит в соответствии с типом указателя

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

Time *pt;

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

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

тип указателя фактический тип объекта

Раннее (статическое) связывание – на этапе компиляции

Что делать, чтобы вызвать метод класса TimeDate?

1. Явное преобразование типа указателя – не всегда возможно

((TimeDate*) pt)->printTime();

2. Позднее (динамическое) связывании – на этапе выполнения Виртуальные методы.

virtual void printTime();

10

Вызов методов происходит в соответствии с типом объекта