Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тех прог.doc
Скачиваний:
38
Добавлен:
14.11.2019
Размер:
3.59 Mб
Скачать

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

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

Программа 60. Производный класс личных данных

Изменим программу 58 так, чтобы дата входила в класс Pers не как объект класса Date, а за счет объявления класса Pers производным от класса Date.

В класс Date добавим оператор присваивания, объявление класса разместим в модуле DateCls1.

// Файл DateCls1.h

#ifndef DateCls1H

#define DateCls1H

class Date // Класс для работы с датами

{

int d, m, y; // Поля класса: День, месяц, год

static int d0, m0, y0; // Начальная дата

static int dw0; // День недели начальной даты.

public:

Date& operator=(Date& D) // Оператор присваивания

{ d = D.d; m = D.m; y = D.y; return *this; }

/* Остальное как в файле DateCls.h */

#endif

Содержимое файла DateCls1.cpp совпадает с содержимым файла DateCls.cpp из программы 57.

Для класса Pers, производного от класса Date, создадим модуль PrsDeriv.

// Файл PrsDeriv.h

#ifndef PrsDerivH

#define PrsDerivH

#include "DateCls1.h" // Подключение класса Date

#include <iostream.h>

#include <fstream.h>

#include <string.h>

class Pers : public Date // Класс Pers – производный от Date

{

char* name; // Строка с фамилией и инициалами

public:

// Остальная часть класса не изменяется, см. программу 57

};

Класс Persons оставляем без изменений.

Наследование означает, что все поля и методы класса Date являются теперь полями и методами класса Pers. Ключевое слово public перед Date означает, что все открытые члены класса Date остаются открытыми, становясь членами класса Pers.

В реализацию класса Pers внесем изменения, приводимые ниже.

// Файл PrsDeriv.cpp

#include "PrsDeriv.h"

#include "DateCls1.h"

Pers :: Pers(char *s, Date D) : Date(D) // Конструктор

{

name = new char [strlen(s)+1]; // Выделение памяти

strcpy(name, s); // Копирование имени

}

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

Pers :: Pers() : Date() // Конструктор по умолчанию

{ // Текущая дата как дата рождения

name = NULL; // Пустое имя

}

Pers::Pers(Pers& ps) : Date(ps) // Конструктор копирования

{

name = new char [strlen(ps.name) + 1];// Выделение памяти под имя

strcpy(name, ps.name); // Копирование имени

}

В качестве аргумента конструктору базового класса Date передается объект ps производного класса Pers. Это допустимо, так как в производном классе есть все, что есть в базовом классе.

Pers& Pers :: operator = (Pers& ps) // Перегрузка оператора присваивания

{

if (this != &ps){ // Если присваивание не самому себе,

delete[] name; // удаление старого имени

name = new char [strlen(ps.name) + 1]; // Память под новое имя

strcpy(name, ps.name); // Копирование имени

this->Date::operator=(ps); // копирование даты

}

return *this; // Возврат ссылки на объект

}

В операторе присваивания дату, содержащуюся в объекте ps, нужно скопировать в данный объект. Для этого через указатель this явным образом вызывается функция-оператор присваивания класса Date, которой в качестве аргумента передается ps. Присваивание вида:

d = ps.d; m = ps.m; y = ps.y;

недопустимо, так как закрытые члены d, m, y класса Date недоступны для функций производного класса Pers, хотя и являются членами этого класса «по наследству». Присваивание дат можно произвести без использования this инструкцией:

Date :: operator=(ps);

так как функция, вызываемая в методе класса, «знает», что должна использовать данные текущего объекта.

Все остальное в файле PrsDeriv.cpp совпадает с файлом Person.cpp.

Для испытания производного класса Pers можно использовать функцию man из файла MainPers.cpp, включив в него вместо директивы

#include "Person.h"

директиву

#include "PrsDeriv.h"

Созданная программа будет работать так же, как программа 58.