Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР_08_Классы-VC++7-2003.doc
Скачиваний:
3
Добавлен:
01.04.2025
Размер:
946 Кб
Скачать
☆

Модификаторы доступа

Доступность данных и функций класса квалифицируется следующими модификаторами доступа:

  • public – члены класса являются открытыми; ими можно пользоваться без ограничений в любом месте программы; доступ имеют пользователи объекта, сам объект и объект производного класса;

  • private – члены класса являются закрытыми; с ними могут работать только объекты данного класса;

  • protected – члены класса являются защищенными; доступ к ним ограничен только объектами данного класса и классов, производных от него.

Описание и реализация класса

Для эффективного использования класса фазы описания (definition) и реализации (implementation) разделены на два отдельно компилируемых файла. В файле описания (заголовочный header-файл) задаются имя класса и перечень членов классов: данных и интерфейсов функций, обрабатывающих эти данные (методы). В модуле реализации (.cpp-файл) даны тела методов.

Например, header-файл “Classes.h” содержит описание класса CParent:

…

class CParent : public CBase

{

public:

CParent();

CParent(double Value);

virtual ~CParent();

protected:

double* Y;

double Num;

double Den;

public:

double X;

virtual double Method();

double get_Y();

};

Тогда файл “Classes.cpp” содержит реализацию класса CParent:

#include "stdafx.h"

#include "Classes.h"

CParent::CParent(double Value)

{

cout << " CParent Constructor" << endl;

X=Value;

Y=new double(0);

}

CParent::~CParent()

{

cout << " CParent Destructor" << endl;

delete Y;

}

double CParent::Method()

{

Num=sin(X);

Den=cos(X);

double temp=Num/Den;

*Y=temp;

return temp;

}

double CParent::get_Y()

{

return *Y;

}

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

Конструктор – это специальная функция класса, предназначенная для инициализации данных объекта класса при его создании (конструировании). Имя конструктора совпадает с именем класса, и он не возвращает никакого значения. Конструктору можно передать любое количество параметров (в примере один параметр). Например:

class CParent : public CBase

{

double* Y; // закрытая переменная класса

public:

CParent(double Value) // конструктор

{

Y=new double(0); // инициализация закрытого члена класса

} // с захватом динамической памяти

…

Все методы класса могут быть виртуальными, за исключением конструктора.

Деструктор класса

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

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

…

class CParent : public CBase

{

double* Y; // закрытая переменная класса

public:

CParent(double Value) // конструктор

{ Y=new double(0); } // захват динамической памяти

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

{delete Y; } // освобождение динамической памяти

…

Имя деструктора совпадает с именем класса, но оно начинается с символа ~ (тильда) в качестве напоминания его связи с конструктором. Деструктор не возвращает никакого значения и не имеет параметров. Деструктор класса может быть объявлен виртуальным. Это позволяет вызвать требуемый деструктор с помощью указателя на базовый класс. Если указатель в данный момент ссылается на объект одного из производных классов, то будет вызван деструктор соответствующего класса. Деструктор класса, производного от класса с виртуальным деструктором, сам является virtual-деструктором.

Виртуальная функция

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

virtual double Method();

Абстрактная (чисто виртуальная) функция

Функция, которая не имеет реализации, называется абстрактной (чисто виртуальной). Ее заголовок приравнивается нулю. Абстрактная функция обязательно должна быть реализована в классе-наследнике. Например:

virtual double Method()=0;

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

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

class CBase

{

public:

virtual double Method()=0;

};

Наследование данных и методов

Гибкость языка программирования определяется трудоемкостью подстройки существующих программных модулей к новым требованиям заказчика программного обеспечения (ПО). Степень полезности уже разработанных частей ПО значительно повышается, если существует возможность, не изменяя того, что написано, добавлять к ним новые свойства, модифицировать их функционирование или убирать свойства, ставшие ненужными, наследуя при этом большую часть свойств. В языке С++ в распоряжение программиста предоставлена целая иерархия классов и подклассов. Большинство программ пишется с использованием сотен существующих классов и методов, которые объединены в библиотеки (например, библиотека классов Microsoft Foundation Classes - MFC). Появляется возможность создавать объекты существующих классов и посылать им сообщения в виде методов или создавать классы, производные от существующих, изменив в них то, что надо, и работать с объектами этих новых классов.

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

Производный (derived или child) класс является основой для реализации механизма наследования свойств базового (base или parent) класса, а также средством подстройки класса к нуждам пользователя. Например, базовый класс CParent:

class CParent : public CBase

{

public:

CParent();

CParent(double Value);

virtual ~CParent();

protected:

double* Y;

double Num;

double Den;

public:

double X;

virtual double Method();

double get_Y();

};

Производный от класса CParent класс CChild:

class CChild : public CParent

{

public:

CChild();

CChild(double Value);

virtual ~CChild();

virtual double Method();

double Method(double x);

};

Производный класс наследует все данные и методы базового класса. В дополнение к ним он может приобрести новые данные и методы, не содержащиеся в базовом классе. Класс CChild наследует переменные Y, Num, Den, X и метод get_Y() базового класса CParent. Кроме того, класс CChild переопределяет (overriding) метод Method(), внося в него новую функциональность, и перегружает (overloading) его методом Method(double) для достижения своих специфических целей.

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

Постановка задачи

  1. Создать иерархию классов CBase <- CParent <- CChild реализующих обработку арифметического выражения Y(x)=Num(x)/Den(x). Причем

  • базовый класс CBase – абстрактный

    • объявляет интерфейс виртуальной, абстрактной функции Method(), которая должна вычислять арифметическое выражение Y(x); функция Method() не принимает параметров и возвращает значение double результата;

  • дочерний класс CParent

    • наследует класс CBase;

    • инициализирует в конструкторе защищенную переменную Y нулем;

    • реализует открытую виртуальную функцию Method(); функция вычисляет числитель Num, знаменатель Den, дробь, присваивает результат защищенной переменной Y и возвращает значение дроби;

    • открытую переменную X (аргумент арифметического выражения), значение которой получает при конструировании;

    • защищенные переменные: *Y (результат выражения Y(x)), Num (числитель дроби), Den (знаменатель дроби);

  • младший дочерний класс CChild

    • наследует класс CParent;

    • переопределяет (overriding) открытую виртуальную функцию Method(), в которой результат дроби Y(x) удваивается;

    • перегружает (overloading) функцию Method(double), которая получает аргумент x в качестве параметра и возвращает значение числителя дроби Num(x).

  1. Конструкторы и деструкторы классов CBase,CParent, CChild снабдить выводами на консоль сообщений для трассировки выполнения приложения.

  2. Создать объект класса CParent для аргумента X. Вычислить арифметическое выражение, обратившись к методу класса Method().

  3. Создать динамически объект класса CChild для аргумента X. Вычислить арифметическое выражение, обратившись к переопределенному виртуальному методу класса Method() и перегруженному методу Method(double) вычисления числителя исходной дроби.

Требования

  • Оформить вычисления в виде консольного приложения.

  • Результаты вывести на экран с помощью стандартной библиотеки <iostream.h>.

  • В отчет включить тексты файлов основной программы, объявления классов, реализации классов и результаты расчета на экране.

Пример:

Задано при