ООП — Лабораторные работы


Чтобы посмотреть этот PDF файл с форматированием и разметкой, скачайте его и откройте на своем компьютере.








В. С. Романчик, А. Е. Люлькин




С++

ЛАБОРАТОРНЫЕ РАБОТЫ

по курсу «МЕТОДЫ ПРОГРАММИРОВАНИЯ»


Учебно
-
методическое пособие

для студентов механико
-
математического факультета











МИНСК

БГУ

2005


2

УДК 681.142.2(072)

ББК 32.973.26
-
018.1я73

Р6
9

А в т о р ы :

В. С. Романчик, А. Е. Люлькин

Р е ц е н з е н т ы:

кандидат физико
-
математических наук, доцент
Галкин И. М.,

кандидат физико
-
математических наук, доцент,
Суздаль С. В.



Рекомендовано Ученым советом механико
-
математического факультета БГ
У

29 марта 2005 года, протокол № ___








В пособии рассматриваются шесть лабораторных работ, выполняемых студентами 2
-
го курса
при изучении вопросов, связанных с программированием на языке
C
++ . Эти вопросы я
в
ляются
составной частью курса “Методы прог
раммирования”, изучаемого студентами 1
-
го

2
-
го курсов
механико
-
математического факультета. Для выполнения каждого задания отводится 2
-
3 недели.
Для выполнения всех заданий отводится 14 недель.


УДК 681.142.2(072)

ББК 32.973.26
-
018.1я73





Коллектив автор
ов, 2005



БГУ, 2005




3


Лабораторная работа № 1

Тема. Простейшие классы и объекты

Теоретическое введение.
Классы представляют абстрактные
типы данных с открытым интерфейсом и скрытой внутренней
реализацией. В классах реализованы базовые принципы
о
бъектно
-
ор
иентированного программирования
(
ООП):

1) абстракция данных;

2) инкапсуляция

в классах объединяются данные и методы
(функции) для работы с ними, так как лишь через методы возможен
доступ к сокрытым данным класса;

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

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

4) полиморфизм

возможность использования одних и тех же
методов для работы с различными объектами
базового и порожде
н-
ных им классов
.

Определение простейшего класса без наследования имеет вид:


class имя_класса 

//
по умолчанию раздел private

частные члены класса

public: // открытые функции и переменные класса

;

Имя класса является новым типом данных. Понятию переменной
данного типа соответствует понятие объекта класса. Список членов
класса включает о
писание данных и функций. Функции, описания
которых находятся в определении класса, называются функциями
-
членами класса.

Переменные и функции, объявленные в разделе класса по
умолчанию или явно как
private,
имеют область видимости в пределах
класса. Их мож
но сделать видимыми вне класса, если объявить в
разделе
public:
.

Обычно переменные объявляются в разделе
private
, а
функции в разделе
public
.

Классами в С++ являются также структуры
(struct
)
и объединения
(union
).
В отличие от класса члены структуры по умо
лчанию
являются открытыми, а не закрытыми. Кроме того, объединения не
могут наследоваться и наследовать.

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

4

функций
-
членов класса помещаются вне класса. При этом перед
именем функции указывается
имя_класса::
.

тип и
мя_класса:: имя_функции (описание аргументов)


/*тело функции*/


Вызов функций осуществляется одним из двух способов:


имя_объекта.имя_функции(аргументы);

указатель_на_объект
-
> имя_функции(аргументы);

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

Функции
-
«друзья» класса, объявляемые в классе со
спецификатором
friend
, указатель
this
не содержат. Объекты
, с ко
т
о-
рыми работают т
а
кие функции,
должны передаваться в качестве их
аргументов.
Это обычные функции языка С++, которым разр
е
шен
доступ к закрытым членам класса.

Пример.

/*
Создается класс
Student
. Формируется динамический массив объе
к
тов. При
тестировании вы
водится: сформированный список студентов, список ст
у
дентов
заданного факультета, список студентов для заданных факультета и ку
р
са.*/

#include

#include

#include

struct date //
дата

рождения

char daymon[6];

int year;
;

//======= class Student =================

class Student

char name[30]; //private

date t;

char adr[30], fac[20];

int kurs;

public:

Student();

char *getfac();

int getkurs();

void show();

;

S
tudent::Student()

cout<<"Input name:"; cin>>name;

cout<<"Input date of born
\
n";

cout<<"Day.mon:"; cin>>t.daymon;

cout<<"Year:"; cin>>t.year;

cout<<"Input adr:"; cin>>adr;

cout<<"Input fac:"; cin>>fac;


5


cout<<"Input kurs:"; cin>>kurs;



void Student::show()



cout<<"Name :"<
cout<<"Was born :"<
cout<<"Address :"<
cout<<"Fac :"<
cout<<"Kurs
:"<


char *Student::getfac()  return fac; 

int Student::getkurs()  return kurs; 

void spisfac(Student spis[],int n)//
список

студентов

заданного

факульт
е
тата

char fac[20];

cout<<"Input faculty:"; cin>>fac;

for(int i=0;i
if(strcmp(spis[i].getfac(),fac)==0)spis[i].show();



void spisfackurs(Student spis[],int n)

//список студентов з
аданных факультета и курса


int i,k;

char fac[20];

cout<<"Input faculty:"; cin>>fac;

cout<<"Input the course:"; cin>>k;

for(i=0;i
if ((strcmp(spis[i].getfac(),fac)==0)&&(spis[i].getkurs()==k))

s
pis[i].show();



//========= main ================

void main()

 Student *spis;

int n;

cout<<"Input a number of students: "; cin>>n;

spis=new Student [n];

for(int i=0;i
cout<<"=============================
="<
spis[i].show();



spisfac(spis,n);

spisfackurs(spis,n);

delete [] spis;

cout<<"press any key!"

while(!kbhit());




6

Задания для самостоятельного решения

Разработать классы для описанных ниже объектов. Включить в
класс методы
set
(…),
get
(…),
show
(…). Определить другие методы.

1.
Student
: Фамилия, Имя, Отчество, Дата рождения, Адрес, Тел
е-
фон, Факультет, Курс. Создать м
ассив объектов. Вывести:

а) список студентов заданного факультета;

б) списки студентов для каждого факультета и курса;

в) список студентов, родившихся после заданного года.

2.
Abiturient
: Фамилия, Имя, Отчество, Адрес, Оценки. Создать
массив объектов. Выве
сти:

а) список абитуриентов, имеющих неудовлетворительные оценки;

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

в) выбрать
N
абитуриентов, имеющих самую высокую сумму ба
л-
лов, и спи
сок абитуриентов, имеющих полупроходной балл.

3.
Aerof
lot
: Пункт назначения, Номер рейса, Тип самолета, Вр
е
мя
вылета, Дни недели. Создать массив объектов. Вывести:

а) список рейсов для заданного пункта назначения;

б) список рейсов для заданного дня недели;

в) список рейсов для заданного дня недели, время выле
та для к
о-
торых больше заданного.

4.
Book
: Автор, Название, Издательство, Год, Количество стр
а
ниц.
Создать массив объектов. Вывести:

а) список книг заданного автора;

б) список книг, выпущенных заданным издательством;

в) список книг, выпущенных после заданно
го года.

5.
Worker
: Фамилия и инициалы, Должность, Год поступления на
работу, Зарплата. Создать массив объектов. Вывести:

а) список работников, стаж работы которых на данном предпри
-
ятии превышает заданное число лет;

б) список работников, зарплата которых
больше заданной;

в) список работников, занимающих заданную должность.

6.
Train
: Пункт назначения, Номер поезда, Время отправления,
Число общих мест, Купейных, Плацкартных. Создать массив объе
к-
тов. В
ы
вести:

а) список поездов, следующих до заданного пункта н
азначения;

б) список поездов, следующих до заданного пункта назначения и
отпра
в
ляющихся после заданного часа;

в) список поездов, отправляющихся до заданного пункта назнач
е-
ния и имеющих общие места.


7

7.
Product
: Наименование, Производитель, Цена, Срок хран
е
н
ия,
Количество. Создать массив объектов. Вывести:

а) список товаров для заданного наименования;

б) список товаров для заданного наименования, цена которых не
превышает указанной;

в) список товаров, срок хранения которых больше заданного.

8.
Patient
: Фамили
я, Имя, Отчество, Адрес, Номер медицинской
карты, Диагноз. Создать массив объектов. Вывести:

а) список пациентов, имеющих данный диагноз;

б) список пациентов, номер медицинской карты которых нах
о
дится
в з
а
данном интервале.

9.
Bus
: Фамилия и инициалы водите
ля, Номер автобуса, Номер
маршрута, Марка, Год начала эксплуатации, Пробег. Создать массив
объектов. Вывести:

а) список автобусов для заданного номера маршрута;

б) список автобусов, которые эксплуатируются больше 10 лет;

в) список автобусов, пробег у котор
ых больше 10 000 км.

10.
Customer
: Фамилия, Имя, Отчество, Адрес, Телефон, Номер
кредитной карточки, Номер банковского счета. Создать массив объе
к-
тов. Вывести:

а) список покупателей в алфавитном порядке;

б) список покупателей, номер кредитной карточки кото
рых нах
о-
дится в заданном интервале.

11.
File
: Имя файла, Размер, Дата создания, Количество обращ
е-
ний. Создать массив объектов. Вывести:

а) список файлов, упорядоченный в алфавитном порядке;

б) список файлов, размер которых превышает заданный;

в) список фай
лов, число обращений к которым превышает зада
н-
ное.

12.
Word
: Слово, Номера страниц, на которых слово встречается
(от 1 до 10), Число страниц. Создать массив объектов. Вывести:

а) слова, которые встречаются более чем на
N
страницах;

б) слова в алфавитном п
орядке;

в) для заданного слова номера страниц, на которых оно встреча
-
е
т
ся.

13.
House
: Адрес, Этаж, Количество комнат, Площадь. Создать
массив объектов. Вывести:

а) список квартир, имеющих заданное число комнат;

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


8

в) список квартир, имеющих площадь, превосходящую заданную.

14.
Phone
: Фамилия, Имя, Отчество, Адрес, Номер, Время внутр
и-
городских разговоров, Время междугородних разговоров. Созда
ть
массив объектов. Вывести:

а) сведения об абонентах, время внутригородских разговоров кот
о-
рых пр
е
вышает заданное;

б) сведения об абонентах, воспользовавшихся междугородней св
я-
зью;

в) сведения об абонентах, выведенные в алфавитном порядке.

15.
Person
: Фам
илия, Имя, Отчество, Адрес, Пол, Образование,
Год рождения. Создать массив объектов. Вывести:

а) список граждан, возраст которых превышает заданный;

б) список граждан с высшим образованием;

в) список граждан мужского пола.

Тесты

1. Для чего нужны классы?

В
арианты ответа*:

*1) для определения новых типов в программе; 2) для упрощения работы с
функциями; *3) для соединения данных и операций над ними; 4) для упрощ
е-
ния работы с указателями.

2. Методы класса определяют:

*1) какие операции можно выполнять с объек
тами данного класса; 2) какие
типы значений могут принимать данные
-
члены класса; 3) каким образом ре
а-
лизуется защита данных
-
членов класса.

3. Атрибуты (данные
-
члены) класса могут быть:

1) только целыми числами; 2) любыми встроенными типами; *3) любого о
п-
ре
деленного в программе типа.

4. Какая из записей соответствует обращению к атрибуту
arg
класса А в опр
е-
д
е
лении метода этого же класса?

Варианты

ответа:

*1) this

> arg; *2) arg; 3) A

> arg; 4) A

> this

> arg.

5. Если имеется код

class A public: int a;
; A *obj;

то как обратиться к переменной а?

Варианты

ответа:

1) obj.a; 2) (*obj)

> a; *3) obj

> a; 5) obj :: a.

6.
Если

имеется

код

class A public: int a, b, c;; A *obj;

то как обратиться к переменной
b
?

Варианты ответа:

1)

(*
obj
)

>
b
; 2)
A
::
b
; *3) (*
obj
).
b
; 4)
obj


>
a
.
b
.



* Звездочкой в тестах отмечены правильные ответы.


9

7. Каков будет результат выполнения следующего кода:

class A 

public:

int inc (int x) return x++;

int inc (short x) (return x+2;

;

A obj; int y=5;

cout << obj.inc(y); ?

Вариант
ы ответа:

*1) 5; 2) 6; 3) 7; 4) ошибка при компиляции.

8. Каков будет результат выполнения следующего кода:

class A 

public:

int y;

int inc (int x) return y++;

int inc (short x) return x+y;

;

A obj; int y=5; obj.y= 6;

cout << obj.inc(y); ?

Варианты о
твета:

1) 5;
*
2) 6; 3) 11; 4) 7; 5) ошибка при компиляции.

9. Какими по умолчанию объявляются элементы структуры?

Варианты ответа:

1)
private
; *2)
public
; 3)
protected
; 4) по умолчанию не объявл
я
ются.

Лабораторная работа № 2

Тема. Разработка классов

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

Конструктор

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

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

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

+ ,
-
, * , / , % , ^ , & , | , ~ , ! , = , < , > ,+= , [] ,
-
> , ( ) , new, delete
.


10

Оператор
-
функция является членом класса или дружественной
(
friend
) классу. Общая форма оператор
-
функци
и
-
члена класса:

возвращаемый_тип
имя_класса
::operator#(список_аргум)

/*тело функции*/

После этого вместо
operator#(a,b)
можно писать
a#b
. Здесь #
представляет один из введенных выше символов. Примерами
являются операторы
>>
и
<<


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

два.

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

Пример.
Создается класс
Polynom
. В головной программе выпо
л
-
няется тестирование класса.

#include

#include

#include

class Polynom 

int n;

double *koef;

public:

Polynom(); //
конструкторы

Polynom(int
k);

Polynom(int k,double *mas);


Polynom
(
const

Polynom
&
ob
); //конструктор копирования


~Polynom()delete[]koef;

void GiveMemory(int k);

void SetPolynom(int k,double *mas);

void SetDegree(int k)n=k;; //
установить

степень

void CalculateValue(double
x); //
вычислить

значение

int GetDegree()return n;; //
получить степень

double GetOneCoefficient(int i)return(koef[i]);;

Polynom operator+(Polynom ob); //
перегрузка

операторов

Polynom operator*(Polynom ob);

double& operator[](int i)return(koef[i
]);//
перегрузка
[]

Polynom& operator = (const Polynom p) 

if(&p==this) return *this;

if(koef) delete [] koef;


11

n=p.n;

koef=new double [p.n+1];

for(int i=0;i<=p.n;i++)

koef[i]=p.koef[i];

return *this;



friend ostream& ope
rator<<(ostream& mystream,Polynom &ob);

friend istream& operator>>(istream& mystream,Polynom &ob);

int min(int n,int m)

return (n
int max(int n,int m)

return (n>m)? n:m; 

;

//*********** Polynom() **********************************

Polyno
m::Polynom()

 randomize();

n=random(5);

koef=new double[n+1];

if(!koef)cout<<"Error";getch();return;

for(int i=n;i>=0;i
--
)

koef[i]=random(10)
-
5;



//************* Polynom(int k) *******************************

Polynom::Polynom(int k)

 n=k;

koef=new double[n+1];

if(!koef)cout<<"Error";getch();return;

for(int i=n;i>=0;i
--
)

koef[i]=random(10)
-
5;



//****************** Polynom(int k,double mas[]) ******************

Polynom::Polynom(int k,double mas[])

n=k;

koef=new double[n+1];

if(!
koef)cout<<"Error";getch();return;

for(int i=n;i>=0;i
--
)

koef[i]=mas[i];



//*************** Polynom(const Polynom&ob) *********************

Polynom::Polynom(const Polynom&ob)

n=ob.n;

koef=new double[n+1];

if(!koef)cout<<"Error";getch();return;


for(int i=0;i<=n;i++)

koef[i]=ob.koef[i];



//**************** void GiveMemory(int k) **********************


12

void Polynom::GiveMemory(int k)



if(koef) delete [] koef;

koef=new double[k+1];

if(!koef)cout<<"Error";getch();return;



//***********
********* SetPolynom **************************

void Polynom::SetPolynom(int k,double *mas)

 n=k;

if(koef) delete [] koef;

koef = new double [n+1];

for(int i=n;i>=0;i
--
)

koef[i]=mas[i];



//*************** CalculateValue **************************
***

void Polynom::CalculateValue(double x=1.0)

 double s;

int i;

for(s=koef[0],i=1;i<=n;i++)

s=s+koef[i]*pow(x,i);

cout<<"f("<


//**************** Polynom operator+(Polynom ob) ***************

Polynom Polynom::operator+(Po
lynom ob)

 int i;

Polynom rab;

rab.GiveMemory(max(n,ob.GetDegree()));

for(i=0;i<=min(n,ob.GetDegree());i++)

rab.koef[i]=koef[i]+ob.GetOneCoefficient(i);

if(n


for(i=min(n,ob.GetDegree())+1;i<=ob.GetDegree();i++)

rab.
koef[i]=ob.GetOneCoefficient(i);

rab.n=ob.GetDegree();



else



for(i=min(n,ob.GetDegree())+1;i<=n;i++) rab.koef[i]=koef[i];

rab.n=n;



return rab;



//*************** Polynom operator*(Polynom ob) ***************

Polynom Polynom::oper
ator*(Polynom ob)



int i,j,k;

double s;


13

Polynom rab;

rab.GiveMemory(n+ob.GetDegree());

for(i=0;i<=n+ob.GetDegree();i++)

 s=0;

for(j=0;j<=n;j++)

for(k=0;k<=ob.GetDegree();k++)

if(j+k==i)s=s+koef[j]*ob.GetOneCoefficient(k);

rab.koef[i]=s;



rab.n=n+ob.GetDegree();

return rab;



//********** ostream& operator<<(ostream& mystream,Polynom &ob) ******

ostream& operator<<(ostream& mystream,Polynom &ob)


char

c
=' '; //пропустим “+” перед первым коэффициентом


for(int
i=ob.n;i>=0;i
--
)

 double ai=ob.koef[i];

if(ai==0) continue;

else if(ai>0) mystream<
if(i==0) continue; else mystream<<"x";

if(i==1) continue; else mystream<<"^"<
if(ai!=0)c='+';



if(c==' ')mystream<<0;

mystream<
return mystream;



//********* istream& operator>>(istream& mystream,Polynom &ob) *

istream& operator>>(istream& mystream,Polynom &ob)



int i;

cout<<"Enter Degree:"; mystream>>ob.n; cout<
for(i=ob
.n;i>=0;i
--
)



cout<<"Enter koeff "<>ob.koef[i];



return mystream;



//******************** MAIN ****************************

int main(int argc, char* argv[])

 const int m=3;

Polynom f,g,masp[m],*p1,s;

int n=5,i;


double K[6]=1.0,3.2,0.0,4.1,0.0,1.1;

p1=new Polynom(n,K);

cout<<*p1;

p1
-
>CalculateValue(2.0);


14

cin>>f;

cout<<" f(x)= "; cout<
cout<<" g(x)= "; cout<
s=f+g;

cout<<"f(x)+g(x) = "; cout<
s=f*g;

cout<<" f(
x)*g(x) = "; cout<
s=masp[0]; cout<
for(i=1;i
 s=s+masp[i]; cout<
cout<<"Summa: "; cout<< s;

while(!kbhit());

delete

p
1;


return
0;



Задания для самостоятельного решения

Разработать перечисленные ниже
классы. При разработке ка
ж
дого
класса возможны два варианта решения: а) данные
-
члены класса
представляют собой переменные и массивы фиксированной размерн
о-
сти; б) память для данных
-
членов класса выделяется динамически.

1. «
Комплексное число
»


Complex
. Кла
сс должен содержать н
е-
сколько конструкторов и операции для сложения, вычитания, умн
о-
жения, деления, присваивания. Создать два ве
к
тора размерности
n
из
комплексных коорд
и
нат. Передать их в функцию, которая выполняет
сложение компле
к
с
ных векторов.

2. Определить класс «
Дробь
»


Fraction
в виде пары
(
)
,
mn
. Класс
должен содержать несколько конструкторов. Реализовать методы для
сложения, вычитания, умножения и деления дробей. Перегрузить оп
е-
рации сложения, вычитани
я, умножения, деления, присваивания и
операции отношения. Создать массив объектов и передать его в фун
к-
цию, кот
о
рая изменяет каждый элемент массива с четным индексом
путем добавления следующего за ним элемента ма
с
сива.

3. Разработать класс «
Вектор
»


Vecto
r
размерности
n
. Опред
е-
лить несколько конструкторов, в том числе конструктор копирования.
Реализовать методы для вычисления модуля вектора, скалярного пр
о-
изведения, сложения, вычитания, умножения на константу. Перегр
у-
зить операции
сложения, вычитания, умножения, инкремента, декр
е-
мента, индексирования, присваивания для данного класса. Создать
массив объектов. Написать функцию, которая для заданной пары ве
к-
торов будет определять, являются ли они коллинеарными или ортог
о-
нальными.


15

4. О
пределить класс «
Квадратная матрица
»


Matrix
. Класс до
л-
жен содержать несколько конструкторов, в том числе конструктор к
о-
пирования. Реализовать методы для сложения, вычитания, умнож
е
ния
матриц; вычисления нормы матрицы. Перегрузить операции сл
о
ж
е-
ния, вычит
ания, умножения и присваив
а
ния для данного класса. Со
з-
дать массив объектов класса
Matrix
и передать его в функцию, к
о
т
о-
рая изменяет
i
-
ю матрицу путем возведения ее в квадрат. В голо
в
ной
программе вывести результат.

5. Разработать
класс
«Многочлен»


Polynom
степени
n
. Нап
и-
сать несколько конструкторов, в том числе конструктор копирования.
Реализовать методы для вычисления значения полинома; сложения,
вычитания и у
м
ножения полиномов. Перегрузить операции сло
жения,
вычитания, умножения, инкремента, декремента, индексирования,
присваивания. Создать массив объектов класса. Передать его в фун
к-
цию, вычисляющую сумму полиномов массива и возвращающую п
о-
лином
-
результат, к
о
торый выводится на экран в головной программе
.

6. Определить класс
«Стек»


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

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

8. Определить класс «
Строка
»


String
длины
n
. Написать н
е-
сколько конструкторов, в том числе конструктор копирования. Реал
и-
зовать методы для выполнения конкатенации строк, извлечения си
м-
вола из з
а
данной позиции, сравнения строк. Перегрузить опе
рации
сложения, индексирования, отношения, добавления
(
)
+=
, присваив
а-
ния для данного класса. Со
з
дать массив объектов и передать его в
функцию, которая выполняет сортировку строк.

9. Разработать класс «
Множество (целых чисел, символо
в, строк

и т. д.)»


Set
мощности
n
. Написать несколько конструкторов, в том
числе конструктор копирования. Реализовать методы для опред
е
ления
принадлежности заданного элемента множеству, пересечения, объ
е-

16

динения, разности двух множеств. Перегрузить операц
ии слож
е
ния,
вычитания, умножения (пересечения), индексирования, присва
и
вания.
Создать массив объектов и передавать пары объектов в функцию, к
о-
торая строит множ
е
ство, состоящее из элементов, входящих только в
одно из заданных множеств, т. е.
(
)
(
)
\
ABAB

, и возвращает его в
головную пр
о
грамму.

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

11. Составить описания класса, обеспечивающего представление
матрицы заданного размера
n

m
и любого мин
ора в ней. П
а
мять для
матрицы выделять динамически. Написать несколько конструкт
о
ров,
в том числе конструктор копирования. Реализовать методы для от
о-
бражения на экране как матрицы в целом, так и заданного м
и
нора, а
также для изменения минора; сложения, выч
итания, умножения м
и-
норов. П
е
регрузить операции сложения, вычитания, умножения и
присваивания для данного класса. Со
з
дать массив объектов данного
класса и передать его в функцию, которая изменяет для
i
-
й матрицы
ее минор путем умн
ожения на константу.

12. Построить класс «
Булев вектор»



BoolVector
размерности
n
.
Определить несколько конструкторов, в том числе конструктор коп
и-
рования. Реализовать методы для выполнения поразрядных конъюн
к-
ции, дизъюнкции и от
рицания векторов, а также подсчета числа ед
и-
ниц и нулей в векторе. Реализовать те же действия над векторами с
помощью перегруженных операций. Перегрузить операции отнош
е-
ния и присваивания для данного класса. Создать массив объектов. П
е-
редавать объекты в фу
нкцию, которая будет их изменять по формуле
AAB
=
.

13. Реализовать класс «
Троичный вектор»



Tvector
размерности
n
. Ко
м
поненты вектора принимают значения из множества


0,1,
X
.
Два троичных вектора
t
k
=(
t
1
k
,…,t
n
k
) и

t
l
=(
t
1
l
,…,
t
n
l
) называются ортог
о-
нальными, е
с
ли существует такое
i
, что
t
i
k
,
t
i
l

0,1 и
t
i
k

t
i
l
. Операция

17

пере
сечения не ортогональных векторов выполняется покомпонентно
по следу
ю
щим правилам: 1

1=1

X
=
X

1=1, 0

0=0

X
=
X

0=0,
X

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

14. Определить класс «
Булева матрица»



BoolMatrix

размерн
о-
сти
n

m
. Класс должен содержать несколько конструкторов, в том
чи
с
ле конструктор копирования. Реализовать методы для логического
слож
е
ния (дизъюнкции), умножения и инверсии матриц. Реализовать
мет
о
ды для подсчета числа единиц в матрице и лексикографического
упорядочения строк. Перегрузить операции для логического слож
е-
ния, умножения и инверсии матриц, а также операцию присва
и
вания.
Созд
ать массив объектов класса
BoolMatrix
.
Передавать об
ъ
екты в
функцию, которая их изменяет по формуле
AAB
=
.

Тесты

1. В какой строке допущена ошибка?

class X 

int a;

int f() const; //1

int g() return a++;
//2

int h() const return a++; //3

;

Варианты ответа:

1) здесь нет ошибок; (*) 2) //3; 3) //2; 4) //1.

2. Выберите три верных утверждения:

[1] статическая функция
-
член класса, не обладает указателем
this
;

[2] статическая функция
-
член класса, мож
ет быть ви
р
туальной;

[3] в классе не может быть двух функций: статической и нестатич
е
ской

с одним
и тем же именем и списком параметров;

[4] статическая функция в классе не может быть объявлена
const
.

Варианты ответа:

1) все утверждения не верны; (*) 2) [
4]; (*) 3) [3]; 4) [2]; (*) 5) [1].

3 Правильно ли перегружены функции?

class X 

static void f();

void

f
()
const
;

;

Варианты ответа:

*1) нет; 2) да; 3) да, если убрать
const
.

4. Какие из операторов не могут быть перегружены?


18

Варианты ответа:

1)
n
ew
; *2) . ; 3) * ; 4) []; 5) ().

5. Что будет выведено?

#include < iostream.h >

class X 

int a;

public:

X() : a(1) 

X& operator++() a++; return *this;;

X& operator++(int) a
--
; return *this;;

friend ostream& operator<<(ostream&, X
&);

;

ostream& operator<<(ostream& _stream, X& _x) 

_stream << _x.a;

return _stream;



void main() 

X x;

cout << ++x;

cout
<<
x
++;



Варианты ответа:

1) ничего; *2) 21; 3) 12; 4) 22; 5) 11.

6. Даны следующие три свойства, которыми об
ладает функция
-
член кла
с
са:

[1] функция имеет право доступа к закрытой части объявления класса;

[2] функция находится в области видимости класса;

[3] функция должна вызываться для объекта класса (имеется указатель this).

Какими из этих свойств обладает дру
жественная функция?

Варианты ответа:

1) [3]; 2) ни одним; 3) [2]; *4) [1].

7. Какие функции являются неявно inline? Выберите три варианта ответа.

[1] все дружественные функции;

[2] дружественные функции, определенные в классе;

[3] неявный конструктор по ум
олчанию;

[4] неявный деструктор по умолчанию;

[5] виртуальные функции.

Варианты ответа:

1) [5]; *2) [4]; *3) [3]; *4) [2]; 5) [1].

8. Дан следующий код:

class

X



friend

void

f
(
X
&);

;

С помощью какого синтаксиса может быть вызвана функция f?

Варианты
ответа:

1) f не может быть вызвана, т. к. она объявлена как private; 2)
X

x
;
X
::
f
(
x
); 3)
X

x
;
f
(&
x
); 4)
X

x
;
x
.
f
(
x
); *5)
X

x
;
f
(
x
).


19

Лабораторная работа № 3

Тема. Классы для работы с динамическими структур
а
ми
данных

Теоретическое введение
. Объекты классов
могут храниться в в
и-
де массивов или динамических связных списков.
Если класс содержит
конструктор, массив может быть инициализирован, причем
конструктор вызывается столько раз, сколько задается элементов
массива:
samp

ob
[4]=1,2,3,4;

Список инициализации

это сокращение общей конструкции:

samp ob[4]=samp(1,2),samp(3,4),samp(5,6),samp(7,8);

При создании динамических объектов используется оператор
new
,
который вызывает конструктор и производит инициализацию. Для
разрушения динамического объекта использует
ся оператор
delete
,
который может помещаться в деструкторе.

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

Пример.
Создается класс
Tree
(бинарное дерево). Информацио
н-
ная часть узла дерева содержит целое число. Тестиро
вание класса в
ы-
полн
я
ется с помощью меню, которое позволяет сформировать дерево,
вывести содержимое его узлов в порядке возрастания, найти узел по
ключу, вывести содержимое листьев дерева (вершин, не имеющих п
о-
то
м
ков).

#
include
"
vip
\
menu
.
cpp
" //реализация ра
боты с меню

#include

#include

#include

char bufRus[256];

char*Rus(const char*text)

CharToOem(text,bufRus);

return bufRus;

struct node





int

n
; //информационное поле узла дерева


20


int count;

no
de*left,*right;

;

class Tree



public:

node*root;

Tree
()
root
=0;


Tree
(
int

t
); // Формирование дерева из
t
случайных чисел


void CopyTree(node*&rootnew,node*rootold);

/* Копирует дерево с корнем rootold в дерево с корнем rootnew. В р
езульт
а
те
деревья находятся в различных динамических участках пам
я
ти.*/


Tree
(
const

Tree
&
ob
); //конструктор копирования

// Рекурсивная функция, используемая в деструкторе (освобождение памяти)

void DelTree(node *wer);

~Tree()DelTree(root);

void P
ush(node*&wer,int data);//
Вставка

элемента

в

дерево

void

Look
(
node
*
wer
); //
-
Вывод дерева на экран

node*Find(node*wer,int key); //
Поиск

по

ключу

void PrintLeaves(node *wer); //
Вывод

листьев

дерева

на

экран

;

//********************** T
ree::Tree(int t) *******************

Tree::Tree(int t)



root=0;

for(int i=0;i
Push(root,random(10)
-
5);



void Tree::CopyTree(node*&rootnew,node*rootold)



if(rootold
-
>left!=0)

Push(rootnew,(rootold
-
>left)
-
>n);CopyTree(rootnew,rootold
-
>le
ft);

if(rootold
-
>right!=0)

Push(rootnew,(rootold
-
>right)
-
>n);CopyTree(rootnew,rootold
-
>right);



Tree::Tree(const Tree&ob)



if(ob.root==0)root=0;

else 

root=new node;

root
-
>n=ob.root
-
>n;

root
-
>count=1;

root
-
>left=0;


root
-
>right=0;

CopyTree(root,ob.root);






21

void Tree::DelTree(node *wer)



if(wer
-
>left!=0)DelTree(wer
-
>left);

if(wer
-
>right!=0)DelTree(wer
-
>right);

delete wer;



void Tree::Push(node*&wer,int data)



if(wer==0)




wer=new node;

wer
-
>n=data;

wer
-
>left=0;wer
-
>right=0;

wer
-
>count=1;



else if(data-
>n)Push(wer
-
>left,data);

else if(data>wer
-
>n)Push(wer
-
>right,data);

else wer
-
>count++;



void Tree::L
ook(node*wer)



if(wer!=0)



Look(wer
-
>left);

cout<Число
: ")<-
>n<<"
-
"<-
>count;

cout<штук
")<
Look(wer
-
>right);





node* Tree::Find(node*wer,int key)



if(wer==0) return 0;

else if(key-
>n) return Fin
d(wer
-
>left,key);

else if(key>wer
-
>n) return Find(wer
-
>right,key);

else return wer;



void Tree::PrintLeaves(node *wer)



if(wer==0)return;

else if( (wer
-
>left==0)&&(wer
-
>right==0) ) 

cout<Число
: “)<-
>n<<”
-
“<-
>count;

cout<штук
”)<


else



PrintLeaves(wer
-
>left);

PrintLeaves(wer
-
>right);


22





//
--------------------------------
MAIN
----------------------------------------

int main(int argc, char* ar
gv[])



Tree tr;

node *u;

int k=0,max,kol;

char menu[][100]= " PushElement ", " ShowTree ", " FindElement ",

" PrintLeaves ", " EXIT ", ;

kol=5;//
КОЛИЧЕСТВО

СТРОК

МЕНЮ
.
Используется в выравн
и
вании строк

// меню по центру.

//
------------------
ВЫРАВНИВАНИЕ СТРОК МЕНЮ ПО ЦЕНТРУ
----------------

max
=
viravnivaniestrok
(
menu
,
kol
);

//
------------------------
МЕНЮ НА ЭКРАНЕ
---------------------------------------


textmode(C80);

while(1)

switch(m
mm(kol,menu,max,k))

 case 0: 

int data;

cout<Введите

число
:");

cin>>data;

tr.Push(tr.root,data);

k=0;break;




case 1: 

if(tr.root==0)cout<Дерево

пустое
");

else



cout<Наше

дерево
:")<
tr.Look(tr
.root);



while(!kbhit());

k=1;break;



case 2: 

if(tr.root==0)cout<Дерево

пустое
");

else




int key;

cout<Введите

искомое

число
:");

cin>>key;

if((u=tr.Find(tr.root,key))!=0)

cout<
Элементов
: ");

cout<
cout<найдено
");

cout<-
>count<штук
");


23




else cout<элементов нет!");




while(!kbhit());

k=2;break;



case 3: 

if(tr.root==0)cout<Дерево

пустое
");


else

cout<Листья
:")<
tr.PrintLeaves(tr.root);



while(!kbhit());

k=3;break;




case 4:

exit(0);








return
0;



Задания для самостоятельного решения

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

Затем разрабатывается класс для работы с используемой динамич
е-
ской структурой данных, которая при тестировании класса может
быть построена путем ввода данных:
a
) с клавиатуры; б) из файла.
Возможны два варианта реш
е
ния:

а) динамическая структура данных по
стоянно хранится в пам
я
ти;

б) динамическая структура данных хранится в файле.

1. Создать класс для работы со стеком. Элемент стека

действ
и-
тельное число. Применить класс для вывода возрастающих серий п
о-
следовательн
о
сти действительных чисел:
a
) в обратном
порядке; б) в
том же порядке (серия

упорядоченная последовательность макс
и-
мальной длины).

2. Построить класс для работы со стеком. Элемент стека

ц
е
лое
число. Ввести две неубывающие последовательности чисел в два ст
е-
ка. Использовать третий стек для слия
ния двух последовательностей в
одну неубывающую.

3. Создать класс для работы со стеком. Элемент стека

си
м
вол.
Сформировать два стека, содержащие последовательности си
м
волов.
Подсчитать общее число элементов в стеках, предусмотреть восст
а-
новление их исход
н
о
го расположения.


24

4. Создать класс для работы со стеком. Элемент стека

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

5. Построить класс для работы с односвязным списком. Э
лемент
списка

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

6. Построить класс для работы с односвязным списком. Элеме
н
ты
списка

целые числа. Сформировать список, упорядочить элеме
н
ты
списка по возра
с
танию, используя сортировку
:
a
) методом выбора; б)
методом пузырька; в) м
е
тодом вставки.

7. Построить класс для работы с односвязным списком. Элеме
н
ты
списка

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

8. Построить класс для работы с односвязным списком. Элеме
н
ты
списка

слова. Создать список, содержащий некоторую последов
а
-
тельность слов. Заменить в списке каждое вхождение заданного слова
другим (также з
а
данным).

9. Построи
ть класс для работы с односвязным списком. Создать
два сп
и
ска:
List
1 и
List
2. Проверить, содержатся ли элементы списка
List
1 в списке
List
2 в указанном списком
List
1 порядке.

10. Построить класс для работы с односвязным списком. Элеме
н-
ты списка

целые чис
ла. Создать список
List
1. Построить список
List
2, содержащий порядковые номера максимальных элементов сп
и-
ска
List
1.

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

действительные числа. Создать список
List
1, содержащий
последовательн
ость
12
, , ... ,
n
xxx
. Построить список
List
2, содерж
а-
щий последовательность
1211
, , , ,..., ,
nnn
xxxxxx
-
.

12. Создать класс для работы с бинарным деревом, узлы которого
содержат целые числа. Построить дерево, затем копию дерева. По
д-
считать число
листьев в нем (листьями называются узлы, не содерж
а-
щие поддерев
ь
ев).

13. Построить класс для работы с бинарным деревом, узлы котор
о-
го содержат действительные числа. Создать дерево. Определить выс
о-
ту дерева (максимальное число узлов, принадлежащих пути от
корня

25

дерева до любого из его листьев). Подсчитать число элементов, ра
в-
ных ма
к
симальному.

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

15. Построить класс для работы со списком. Элемент списка с
о-
держит информацию о заявке на авиабилет: пункт назначения, номер
рейса, фамилию и инициалы пассажира, желаемую дату вылета.

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

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

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

17. Построить класс для работы со списком, который содержит
динамическую информацию о наличии автобусов в парке: номер а
в-
тобуса, фамилию и инициалы водителя,
номер маршрута, признак м
е-
стонахождения автобуса

на маршруте или в парке.

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

18. Решить предыдущую задачу, используя не список, а бина
р
ное
дерево.

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

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

Составить программу, которая обеспечивает первоначальное фо
р-
миров
а
ние списка, производит вывод списка, вводит номер поезда и

26

выводит информацию о нем, вводит название станции назначения и
выводит данные о всех п
о
ездах, следующих до это
й станции.

Тесты

1.

На каком этапе (компиляция, выполнение) происходит выделение памяти под
динамические структуры данных (ДСД)?

2.

Какие основные операции выполняются над следующими ДСД:

1)

стек;

2)

односвязный список;

3)

односвязная очередь;

4)

двусвязная очередь;

5)

бинарн
ое дерево?

3.

Есть ли ошибки в деструкторе дерева:

~Tree()del_tree(root);

void del_tree(Node *root)

if(!root)

delete root;

del_tree(root
-
>left);

del_tree(root
-
>right); ?

4.

Есть ли ошибки в деструкторе списка:

~List()

Node *V;

if(begin)

V=begin;

while(V)


delete V;

V=V
-
>next; ?

Здесь
begin


указатель на начало списка.

Лабораторная работа № 4

Тема.
Шаблоны классов

Теоретическое введение
.
С помощью шаблонов можно создавать
родовые
(generic)
функции и классы. Родовая функция определяет
базовый набор опе
раций, которые будут применяться к разным типам
данных, получаемых функцией в качестве параметра.

Определение функции с ключевым словом
template
(шаблон)
имеет вид:

templateTtype
>тип имя_функции(список аргументов)

//тело функции

Здесь
Ttype


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


27

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

задаваемого при создании объекта. Общая форма объявления шаблона
класса:

template
<
class

Ttype
>
class
имя_класса 

//имена класса, поля класса



Здесь
Ttype


фиктивное имя типа, которое заменится компилятором
на фактическое. Шаблон класса может иметь бол
ьше одного родового
типа данных:

template
<
class

Type
1,
class

Type
2>
class

m

Type
1
a
;
Type
2
b
;

Пример.
Создается шаблон класса для работы с односвязным сп
и-
ском. Тестирование класса выполняется с использованием меню, к
о-
торое позволяет создать список из чисел
типов
integer
,
float
,
double
и
выполнить типичные оп
е
рации с ним.

#include

#include

#include

#include"vip
\
menu.cpp"

void ListForInt();

void ListForFloat();

void ListForDouble();

char bufRus[256];

char*Rus(const char*text)


CharToOem(text,bufRus);

return

bufRus
;



//шаблон класса для работы с односвязным списком

templateclass List 

//внутренний класс, для представления элементов списка


class Node

public:

mytype d;

Node* next;

Node(mytype dat=0)d=dat; next=0;


;

Node* pbeg; //указатель на начало списка

public:

List()pbeg=0; //конструктор

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

Node * Add(mytype d); //добавление в конец списка


Node * Find(mytype key); //
поиск

по

кл
ючу

Node * Insert(mytype key,mytype d); //
вставка

узла
d
после

узла

с


28

//
ключом
key

bool Remove(mytype key); //
удаление

узла


void Print(); //печать списка

;

//*********************~List
() *************************

//ДЕСТРУКТОР. Освобождает память для всех узлов списка

template List::~List()

if(pbeg!=0)

Node* pv=pbeg;

while(pv)

pv=pv
-
>next;

delete pbeg;

pbeg=pv;








//*************************** void Add(mytype d) **********

//Добавляет узел в конец списка и возвращает указатель

//
на

вставленный

узел
.

template List::Node*

List::Add(mytype d)


Node* pv=new Node(d); //Создание нового
узла

if(pbeg==0)pbeg=pv; //первый узел списка


else 

Node* rab=pbeg;

while(rab!=0)

if((rab
-
>next)==0)rab
-
>next=pv;return pv;

rab=rab
-
>next;







//*************************** Node* Find(mytype k
ey)

//Выполняет поиск узла с заданным ключом и возвращает указатель

// на него в случае успешного поиска и 0 в случае отсутствия узла в списке

template List::Node*

List::Find(mytype key)

Node* pv=pbeg;

while(pv)

if((
pv
-
>d)==key)break;

pv=pv
-
>next;



return pv;



//************* Node* Insert(mytype key,mytype d)

//Вставляет в список узел после узла с ключом key и возвращает

// указатель на вставленный узел. Если такого узла в списке нет,

// вставка не выпол
няется и возвращается значение 0


29

template List::Node*

List::Insert(mytype key,mytype d)

if(Node* pkey=Find(key)) //
поиск

узла

с

ключом
key



Node* pv=new Node(d);

//выделение памяти под новый узел и его инициализация


pv
-
>
next
=
pkey
-
>
next
;

//установление связи нового узла с последующим

pkey
-
>next=pv; //установление связи предыдущего узла с новым


return pv;



return 0;



//******************* bool Remove(mytype key)

//Удаляет узел с заданным ключом из спис
ка и возвращает значение true при

//у
с
пешном удалении и false, если узел с таким ключом не найден

template bool List::Remove(mytype key)

if(Node* pkey=Find(key))


if(pkey==pbeg)pbeg=pbeg
-
>next; //удаление из начала списка

el
se //Находим указатель на узел,

Node*rab=pbeg; //стоящий в списке перед

while(rab) //удаляемым узлом.

 //rab
-
этот указатель.



if((rab
-
>next)==pkey)break;

rab=rab
-
>next;



rab
-
>next=pkey
-
>next;



delete pkey;

return true;



return false;



//********************
void

Print
()
-
Печать списка

template void Li
st::Print()

Node*pv=pbeg;

cout<Наш

список
:");cout<
while(pv)

cout<-
>d<<' ';

pv=pv
-
>next;



cout<
//
---------------------------
MAIN
---------------------------------------------

int main(int argc, char*
argv[])

int k=0,max,kol;

char menu[][100]= " ListForInt ", " ListForFloat ",

" ListForDouble ", " EXIT ", ;


30

kol=4; //
КОЛИЧЕСТВО

СТРОК

МЕНЮ
.
Это используется в выра
в
нивании

//строк меню по центру.

//
----
ВЫРАВНИВАНИЕ СТРОК МЕНЮ ПО ЦЕНТРУ
------------------

max
=
viravnivaniestrok
(
menu
,
kol
);

//
-----------------
МЕНЮ НА ЭКРАНЕ
---------------------------------------


textmode(C80);

while(1)

switch(mmm(kol,menu,max,k))

 case 0: 


ListForInt();

k=0;break;



case 1: 

ListForFloat();

k=1;break;



case 2:


ListForDouble();

k=2;break;



case 3:

exit(0);







return 0;



//**
************************* void ListForInt()

//Эта функция вызывается из главного меню.

void ListForInt()

Listl1;

int k=0,max,kol;

char menu[][100]=

 " PrintList ", " Add ", " Find ", " Insert ",


" Remove ", " EXIT ", " Back "

;


kol=7; //КОЛИЧЕСТВО СТРОК МЕНЮ.

max=viravnivaniestrok(menu,kol);

//
------------------------
МЕНЮ НА ЭКРАНЕ
-----------------------------


textmode(C80);

while(1)

switch(mmm(kol,menu,max,k))

 case 0: 

l1.Print();

while(!kbhit())

k
=0;
break
;

case 1: 

cout<

31



int

t
;
cin
>>
t
;

if( (l1.Add(t)) )cout<
else cout<

while(!kbhit());

k=1;b
reak;


case 2: 

cout<

int

t
;


cin
>>
t
;

if(l1.Find(t))cout<и
ске.");


else cout<

while(!kbhit());

k=2;break;


case 3: 

cout<


int

t
;
cin
>>
t
;

cout<а
вить:");


int key;cin>>key;

if( (l1.Insert(key,t)) )cout<вставка

осуществлена
");



else cout<

while(!kbhit());

k=3;break;


case 4: 

cout<


int t;cin>>t;

if( (l1.Remove(t)) )cout<удаление

осуществлено
");


else cout<

while(!kbhit());

k=
4;break;

case 5:exit(0);

  

Таким же образом, как и функция
ListForInt
(), реализуются фун
к-
ции
List
ForFloat
() и
ListForDouble
(), предназначенные для тестиров
а-
ния списков из ч
и
сел типа
float
и
double
, соответственн
о.

Задания для самостоятельного решения

Для разработки шаблонов классов можно использовать результаты
выполнения лабораторных работ № 2 и № 3. При тестировании со
-
зданных шаблонов классов необходимо создавать объекты с разли
ч-
ными допустимыми значениями пар
аметров шаблона (например, ко
м-
поненты вектора могут быть целыми, действительными или ко
м-
плексными чи
с
лами).

1.

Создать шаблон класса для работы со стеком. Применить его
для решения задач № 1

4 (лаб. работа № 3).


32

2.

Создать шаблон класса для работы с одномерным
массивом.
Выполнить тестирование путем создания и обработки массивов, с
о-
держащих элементы различных типов (например, сортировка эл
е-
ментов массивов различными м
е
тодами).

3.

Создать шаблон класса
Vector
размерности
n

(см. задачу № 3,
лаб. работа № 2).

4.

Создать
шаблон класса «Квадратная матрица»


Matrix
ра
з-
мерно
сти
n

n
(см. задачу № 4, лаб. работа № 2).

5.

Создать шаблон класса
Polynom
степени
n
(см. задачу № 5,
лаб. работа № 2) или создать шаблон класса для работы с односвя
з-
ным списком. Применить его для решения
задачи № 5 (лаб. р
а
бота №
3).

6.

Создать шаблон класса для работы с односвязным списком.
При
менить шаблон класса для решения задачи № 6 (лаб. работа №
3).

7.

Создать шаблон класса для работы с односвязным списком.
При
менить шаблон класса для решения задачи №
7 (лаб. работа №
3).

8.

Создать шаблон класса для работы с бинарным деревом. Пр
и-
ме
нить его для сортировки действительных чисел и строк, вводимых
с клавиатуры или из файла.

9.

Создать шаблон класса
Set
(множество) мощности
n
(см. зад
а-
чу № 9, лаб. работа № 2 ) и
ли создать шаблон класса для работы с
односвязным списком. Применить шаблон класса для решения зад
а-
чи № 9 (лаб. работа № 3).

10.

Создать шаблон класса для работы с односвязным списком.
Применить шаблон класса для решения задачи № 10 (лаб. работа №
3).

11.

Создать
шаблон класса, обеспечивающего описание ма
т
рицы
заданного размера
n

m
и любого минора в ней (см. задачу № 11, лаб.
работа № 2) или создать шаблон класса для работы с двусвя
з
ным
списком. Применить шаблон класса для решения задачи № 11 (лаб.
работа № 3).

12.

Соз
дать шаблон класса для работы с бинарным деревом. Пр
и-
менить шаблон класса для решения задачи № 12 (лаб. работа № 3).

13.

Создать шаблон класса для работы с бинарным деревом. Пр
и-
менить шаблон класса для решения задачи № 13 (лаб. работа № 3).

14.

Создать шаблон клас
са для работы с двусвязным списком.
Применить шаблон класса для решения задачи № 15 (лаб. работа №
3).


33

15.

Создать шаблон класса для работы с односвязным списком.
Применить шаблон класса для решения задачи № 16 (лаб. работа №
3).

Тесты

1. Отметьте все утвержде
ния, которые считаете верными:

1) нельзя с помощью шаблона создать функцию с таким же име
нем, как у я
в-
но определенной функции;

2) цель введения шаблонов

создание функций, которые могут обрабат
ы
вать
однотипные данные;

*3) при использовании шаблонов функ
ций возможна перегрузка как с п
о
-
мощью шаблонов, так и функций;

*4) в качестве описания шаблона функции используется прото
тип шаб
л
о
на:

__
template
списокпараметровшаблона

2. Можно ли задать шаблон со значением параметра по умолч
а
нию?

Варианты ответа:

*1) да; 2
) нет.

3. Каков правильный заголовок шаблона?

Варианты ответа:

*1) template; 2) template ; 3) template t>;

4. Сколько параметров может быть у шаблона при определении шаблона
функции?

Варианты ответа:

1) 1; 2)
столько, сколько аргументов у функции; *3) столько, сколько типов и
с
-
пользуется для параметризации.

5. Отметьте правильный вариант описания шаблона семейства функций:

1) template(class T)

void func(T* p1,T* p2)…

2) template ;

void func
(T* p1,T* p2)…

*3) template

void func(T* p1,T* p2)…

4) template

void func(T* p1,T* p2)…

6. Можно ли использовать класс
-
шаблон в качестве базового класса?

Варианты ответа:

*1) да; 2) нет.

Лабораторная работа № 5

Тема. Нас
ледование

Теоретическое введение.
Важнейшим принципом ООП,
реализованным в С++, является
наследование.
Класс, который
наследуется, называется базовым классом, а наследующий класс



34

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

Все члены класса из разделов
public
и
protected
наследуются, а
члены из раздела
private


нет
.
Члены раздела
protected
являются
частными для базового и производного классов. При наследовании
базового класса к
его членам также может объявляться спецификатор
доступ
.

class имя_класса:
доступ
имя_базового_класса

/*члены класса*/

Cпецификатор
доступ
базового класса при наследовании может
принимать одно из трех значений:
public
(по умолчанию),
private,
protected.
Если спецификатор принимает значение
public,
то все члены
разделов
public
и
protected
базового класса становятся членами
разделов
public
и
protected
производного класса. Если доступ имеет
значение
private
, то все члены разделов
public
и
protected
становятс
я
членами раздела
private
производного класса. Если доступ имеет
значение
protected
, то все члены разделов
public, protected
становятся
членами раздела
protected
производного класса.

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

к
онструктор_производного_класса(арг):base(арг)

/*тело конструктора производного класса*/

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

Виртуальные функции и полиморфизм.
Механизм виртуальных
функций в ООП используется для реализации полиморфизма:
созд
а-
ния метода, предназначенного для работ
ы с различными объектами за
счет механизма позднего связывания
(late binding).
Виртуальные
функции объявляются в базовом и производных классах с ключевым
словом
virtual
.
При этом каждый объект класса, управляемого из б
а-
зового класса с виртуальными функциям
и, имеет указатель на
vmtbl
(virtual method table)
,
содержащую адреса виртуальных фун
к
ций. Эти

35

адреса устанавливаются в адреса нужных для данного объекта фун
к-
ций во время выполнения.

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

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

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

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


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

Пример.
Создаются три класса: MyPoint (базовый класс

«То
ч-
ка»), MyEllipse (производный класс о
т класса MyPoint

«Окру
ж
-
ность») и MyCylinder (производный класс от класса MyEllipse

«Ц
и
-
линдр»). Классы объ
явлены в файле
MyClass
.h. Используются кнопки:
Button1

очистка области для рисования (компонент Image1), Button2

создание объекта класса MyP
oint и рисование точки, Button3

соз
-
дание объекта класса MyEllipce и рисование окружности, Button4


создание объекта класса MyCylinder и рисование цилиндра, комп
о-
ненты СSpinEdit1

СSpinEdit4 для задания координат точки и разм
е-
ров фигур, а также перемещ
ения объектов в области рисов
а
ния.

Заголовочный файл
Myclass
.
h

//***************** class MyPoint **************************

class MyPoint 

int x,y;

public:

int GetX()return x;

int GetY()return y;

void SetX(int x1)x=x1;

void SetY(int y1)y
=y1;

MyPoint(int xx=0,int yy=0)x=xx;y=yy;

virtual void Show();

virtual

bool

Checking
();


36

// Проверка, не выходит ли точка за пределы области рисования ?


virtual void MoveTo(int x1,int y1);

;

//**************classs MyEllipse ********************
******

class MyEllipse:public MyPoint 

int xa,yb;

public:

int GetXA()return xa;

int GetYB()return yb;

void SetXA(int xa1)xa=xa1;

void SetYB(int yb1)yb=yb1;

MyEllipse(int a=0,int b=0,int c=0,int d=0):MyPoint(a,b)

xa=c;yb=d;

vir
tual void Show();

virtual

bool

Checking
();

// Проверка, не выходит ли окружность за пределы области рисования ?

;

//**************** class MyCylinder ************************

class MyCylinder:public MyEllipse 

int h;

public:

int GetH()return h;


void SetH(int h1)h=h1;

MyCylinder(int X=0,int Y=0,int R=0,int H=0):MyEllipse(X,Y,R,R/2)

h=H;

void Show();

bool

Checking
();

// Проверка, не выходит ли цилиндр за пределы области рисования ?

;

//****************** class MyCylinder *******
*************

bool ExistFigure=false;//Если ExistFigure==false, объект не изображался

MyPoint
*
Figure
;//
-
Указатель на базовый класс
MyPoint
.

Файл

Unit1.Cpp

#include

#pragma hdrstop

#include "Unit1.h"

#include "Myclass.h"

#pragma package(smart_ini
t)

#pragma link "CSPIN"

#pragma resource "*.dfm"

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)

 

//********** Реализация класса
MyPoint
************************

void MyPoint::Show()

( Form1
-
>Image1
-
>Canvas
-
>Pixels[x][y]=c
lRed;

bool MyPoint::Checking()


37

//
-
Проверка, не выходит ли точка за пределы области рисования ?

if((x>=0)&&(x<=Form1
-
>Image1
-
>Width)&&(y>=0)&&

(y<=Form1
-
>Image1
-
>Height))

return true; else return false;



void MyPoint::MoveTo(int x1,int y1)


 // если выходим за область рисования, то точку не сдвигаем.


int a=x,b=y;

x=x1;y=y1;

if(!Checking())x=a;y=b;




//***********Реализация класса
MyEllipse
**********************

void MyEllipse::Show()



Form1
-
>Image1
-
>Canvas
-
>Ellip
se(GetX()
-
xa,GetY()
-
yb,GetX()+xa,GetY()+yb);



// Проверка, не выходит ли окружность за пределы области рисования ?


bool MyEllipse::Checking()



int rabx=GetX(),raby=GetY();

SetX(GetX()
-
xa);SetY(GetY()
-
yb);

if(MyPoint::Checking())




SetX(GetX()+2*xa);SetY(GetY()+2*yb);

if(MyPoint::Checking())





SetX
(
rabx
);
SetY
(
raby
); // вос
c
танавливаем координаты
x
,
y
.


return

true
;






SetX
(
rabx
);
SetY
(
raby
); // вос
c
танавливаем ко
ординаты
x
,
y
.


return false;



//**********Реализация класса MyCylinder ************************

void MyCylinder::Show()



MyEllipse::Show();

Form1
-
>Image1
-
>Canvas
-
>MoveTo(GetX()
-
GetXA(),GetY());

Form1
-
>Image1
-
>Canvas
-
>LineTo(Get
X()
-
GetXA(),GetY()
-
h);

Form1
-
>Image1
-
>Canvas
-
>MoveTo(GetX()+GetXA(),GetY());

Form1
-
>Image1
-
>Canvas
-
>LineTo(GetX()+GetXA(),GetY()
-
h);

SetY(GetY()
-
h);

MyEllipse::Show();

SetY(GetY()+h);



bool MyCylinder::Checking()




38

if(MyE
llipse::Checking())



SetY(GetY()
-
h);

if(MyEllipse::Checking())SetY(GetY()+h);return true;



return false;



void __fastcall TForm1::Button1Click(TObject *Sender)

 // Чистим "графическое" окно

Image1
-
>Canvas
-
>Fill
Rect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

ExistFigure=false;



void __fastcall TForm1::Button2Click(TObject *Sender)



if(ExistFigure==true)delete Figure;

Image1
-
>Canvas
-
>FillRect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

// Рисуем точку, проверив
её попадание в область рисования


Figure=new MyPoint(CSpinEdit1
-
>Value,CSpinEdit2
-
>Value);

ExistFigure=true;

if(Figure
-
>Checking()) Figure
-
>Show();


else

ShowMessage
("Точка не попадает в область рисования!");



void __fastcall TForm1::Button3Click(TObje
ct *Sender)



if(ExistFigure==true) delete Figure;

Image1
-
>Canvas
-
>FillRect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

// Рисуем окружность, проверив её попадание в область рисования


Figure=new MyEllipse(CSpinEdit1
-
>Value,CSpinEdit2
-
>Value,

CSpinEdit3
-
>
Value,CSpinEdit3
-
>Value);

ExistFigure=true;

if(Figure
-
>Checking())Figure
-
>Show();


else

ShowMessage
("Окружность не помещается в область рисования!");



void __fastcall TForm1::Button4Click(TObject *Sender)



if(ExistFigure==true) delete Figure;

Image1
-
>Canvas
-
>FillRect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

// Рисуем цилиндр, проверив его попадание в область рисования


Figure=new MyCylinder(CSpinEdit1
-
>Value,CSpinEdit2
-
>Value,

CSpinEdit3
-
>Value,CSpinEdit4
-
>Value);

ExistFigure=true;

if(Figure
-
>Check
ing())Figure
-
>Show();


else

ShowMessage
("Цилиндр не помещается в область рисования!");



void __fastcall TForm1::CSpinEdit1Change(TObject *Sender)



if(ExistFigure==true)


39

Image1
-
>Canvas
-
>FillRect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

Figure
-
>M
oveTo(CSpinEdit1
-
>Value,CSpinEdit2
-
>Value);

Figure
-
>Show();





void __fastcall TForm1::CSpinEdit2Change(TObject *Sender)



if(ExistFigure==true)

Image1
-
>Canvas
-
>FillRect(Rect(0,0,Image1
-
>Width,Image1
-
>Height));

Figure
-
>MoveTo(CSpinEdit1
-
>
Value,CSpinEdit2
-
>Value);

Figure
-
>
Show
();






Задания для самостоятельного решения

При выполнении данной работы необходимо определить баз
о
вый
класс и производные от него классы. Предусмотреть передачу арг
у-
ментов конструкторам базового класса; испол
ьзование виртуальных и
перегруженных функций; обработку исключительных ситу
а
ций.

Вариант А

В следующих заданиях требуется создать базовый класс (как вар
и-
ант а
б
страктный базовый класс) и определить общие методы
show
( ),
get
( ),
set
( ) и другие, специфиче
ские для данного класса. Создать
производные классы, в которые добавить свойства и мет
о
ды.

Часть методов переопределить. Создать массив объектов базов
о
го
класса и заполнить объектами производных классов. Объекты прои
з
-
водных классов идентифицировать констр
уктором по имени или
иде
н
тификационному номеру.

Вызвать метод
show
( ) базового класса и просмотреть массив об
ъ-
ектов.

Использовать объекты для моделирования реальных ситуаций.

1. Создать базовый класс «Транспортное средство» и произво
д
ные
классы «Автомобил
ь», «Велосипед», «Повозка». Подсчитать вр
е
мя и
стоимость пере
возки пассажиров и грузов каждым транспортным
сре
д
ством.

2. Создать базовый класс «Грузоперевозчик» и производные кла
с-
сы «Самолет», «Поезд», «Автомобиль». Определить время и сто
и-
мость перевозки
для указанных городов и расстояний.

3. Создать аналогичный базовый класс «Пассажироперевозчик» и
производные классы «Самолет», «Поезд», «Автомобиль». Опред
е
лить
время и сто
и
мость передвижения.


40

4. Изменить задания 1

3, чтобы базовый класс стал абс
т
рактным.
Сделать некоторые методы абстрактными.

5. Создать базовый класс «Учащийся» и производные классы
«Школ
ь
ник» и «Студент». Создать массив объектов базового класса и
заполнить этот массив объектами. Показать отдельно студентов и
школьников.

6. Создать базовый
класс «Музыкальный инструмент» и прои
з-
водные классы «Ударный», «Струнный», «Духовой». Создать массив
объектов «О
р
кестр». Выдать состав оркестра, переопределив метод.

7. Определить базовый класс «Множество» и производный класс
«Кольцо» (операции сложения и
умножения обе коммутативные и а
с-
социативные, связанные законом дистрибутивности; сложение обл
а-
дает обратной операцией

вычитанием). Ввести кольца целых ч
и
сел,
многочленов, систему классов целых чисел, сравнимых по мод
у
лю.
Кольцо является полем, если в не
м определена операция деления,
кроме деления на нуль. Рациональные числа, дробно раци
о
нальные
функции.

8. Создать абстрактный класс «Работник фирмы» и производные
классы «Менеджер», «Администратор», «Программист».

9. Создать базовый класс «Домашнее животно
е» и производные
классы «Собака», «Кошка», «Попугай» и др. С помощью конструкт
о-
ра установить имя ка
ж
дого животного и его характеристики.

10. Создать базовый класс «Садовое дерево» и производные кла
с-
сы «Яблоня», «Вишня», «Груша» и др. С помощью конструк
тор
а а
в-
томатически установить номер каждого дерева. Принять реш
е
ние о
пересадке каждого дерева в зависимости от возраста и плод
о
ношения.

Вариант Б

1. Создать класс
Item
(единица хранения в библиотеке), содерж
а-
щий данные
-
члены:
invNumber


инвентарный номер и
taken


взято
на руки или имее
т
ся в наличии, а также методы:

virtual

void

Show
(); //показать информацию о единице хр
а
нения

bool

isAvailable
(); // есть ли единица хранения в наличии ?

int

GetinvNumber
(); //возвращает инвентарный номер

void

Take
(); // опер
ация «взять»

void

Return
(); // операция «вернуть»

Построить производные классы
Book
и
Magazin
. Класс
Book
с
о-
держит

данные
-
члены
: author, title, publisher, year
и

методы
: A
u
thor();

Title(); Publisher(); YearOf Publishing(); Show().

Класс
Magazin
включает

данные
-
члены
: volume; number; year; t
i
tle
и

методы
: Volume(); Title(); Number(); Year(); Show().


41

2. Создать базовый класс
Polygon
(многоугольник). Класс до
л
жен
содержать методы для рисования многоугольника, вычисления пер
и-
метра, нахождения площади и др. П
остроить производный класс
Tr
i-
angle
(треугольник), содержащий также методы для нахождения то
ч
ки
пересечения медиан, длин медиан, длин биссектрис, координат т
о
чек
пересечения биссектрис, высот треугол
ь
ника.

3. Создать абстрактный класс
Shape
для рисования п
лоских ф
и
гур.
Построить производные классы
Square
(квадрат, который характер
и-
зуется координатами левого верхнего угла и длиной стороны),
Circle

(окружность с заданными координатами центра и радиусом),
Ellipse

(эллипс с заданными координатами вершин описанн
ого вокруг него
прямоугольника), позволяющие рисовать указанные ф
и
гуры, а также
передвигать их на плоскости.

4. Создать класс
CPoint


точка и производные от него классы
CcoloredPoint
и
CLine
. На основе классов
CcoloredPoint
и
CLine
со
-
здать класс
Ccolore
dLine
. Все классы должны иметь методы для уст
а-
новки и получения значений всех координат, а также изменения цвета
и получ
е
ния текущего цвета.

5. Описать базовый класс
Stroka
. Обязательные данные
-
члены
класса: указатель типа
char


для хранения строки; зна
чение типа
int



длина строки.

Методы: конструктор без параметров; конструктор, принимающий
в качестве параметра
C
-
строку (заканчивается нулевым байтом); ко
н-
структор копирования; получение длины строки; очистка строки (сд
е-
лать строку пустой); деструктор.

О
писать производный класс «БИТОВАЯ_СТРОКА» (строки да
н-
ного класса могут содержать только символы ‘0’ и ‘1’). Если в основе
инициализирующей строки встретятся любые символы, отличные от
допустимых, то БИТ
О
ВАЯ_СТРОКА становится пустой. Содержимое
строки рассм
атривается как двоичное представление целого числа со
знаковым разрядом. Отрицательные числа хранятся в дополнительном
коде.

Обязательные методы: конструктор без параметров; конструктор,
принимающий в качестве параметра
C
-
строку; конструктор копиров
а-
ния; д
еструктор; изменение знака числа (перевод числа в дополн
и-
тельный код).

Переопределить следующие операции (длина строки результата в
случае необходимости расширяется влево знаковым разрядом): пр
и-
сваивание; сложение (+); проверка на раве
н
ство (==).


42

6. Созд
ать производный класс «СТРОКА10» (целое неотрицател
ь-
ное десятичное число) от класса «СТРОКА» (описание приведено
выше).

Методы: конструктор без параметров; конструктор, принимающий
в качестве параметра
C
-
строку; конструктор копирования; дес
т
руктор;
метод,
определяющий, можно ли представить данное чи
с
ло в формате
int
; метод, определяющий, равно ли число нулю; метод, возвраща
ю-
щий представление числа в виде целого (
int
); метод, удаляющий н
е-
значащие нули.

Переопределить операции: сложение (+); проверка на больш
е (по
значению) (>); проверка на меньше (<); присваивание (=).

7. Создать производный класс «БУЛЕВ ВЕКТОР» (
BoolVector
) от
класса
Vector
. Компоненты принимают значения из множе
с
т
ва 0,1.

Методы: конструктор без параметров; конструктор, принимающий
в кач
естве параметров указатель на массив це
лого типа (если эл
е
-
менты массива содержат числа, отличные от 0 и 1, то создается пустой
вектор) и размер вектора; конструктор копирования; деструктор; м
е-
тод, возвращающий число единиц в векторе; метод, возвращающий
позицию с
а
мой левой единицы в векторе.

Переопределить операции: поразрядная конъюнкция (&); пора
з-
рядная дизъюнкция (|); поразрядная инверсия (~); поразрядная опер
а-
ция ИСКЛЮЧАЮЩЕЕ ИЛИ (^); присваивание (=).

8. Создать производный класс «ТРОИЧНЫЙ ВЕКТОР» от
класса
Vector
. Компоненты принимают значения из множества 0,1,2.

Методы: конструктор без параметров; конструктор, принимающий
в качестве параметров указатель на массив целого типа и размер ве
к-
тора; конструктор копирования; деструктор; проверка двух век
торов
на ортогональность (два троичных вектора называются ортогонал
ь-
ными, если в них существует пара одноименных компонент, имеющих
в одном из векторов значение 0, а в другом

1); метод, возвраща
ю-
щий число компонент в векторе, принимающих значение 2.

Пере
определить операции: присваивание (=); поразрядная кон
ъ-
юнкция (пересечение) двух не ортогональных векторов (&): 0&0=0,
1&1=1, 2&2=2, 0&2=0, 2&0=0, 1&2=1, 2&1=1; индексир
о
вание ([]).

9. Создать производный класс «БУЛЕВА МАТРИЦА» от класса
«ЦЕЛ
О
ЧИСЛЕННАЯ МА
ТРИЦА».

Методы: конструктор без параметров; конструктор, принимающий
в качестве параметров целочисленный двумерный массив, содерж
а-
щий матрицу, и ее размеры
n
и
m
; конструктор копирования; дестру
к-
тор; метод возвращает число единиц в матрице; метод, возвр
а
ща
ющий

43

a
-
каноническую матрицу (в исходной матрице удалены повторя
ю-
щиеся строки; строки составлены в порядке возрастания неотриц
а-
тельных чисел, в качестве двоичных кодов которых ра
с
сматриваются
данные строки).

Переопределить операции: поэлементная конъюнкция
двух матриц
(&); поэлементная дизъюнкция двух матриц (|); поэлементная опер
а-
ция ИСКЛЮЧАЮЩЕЕ ИЛИ двух матриц (^); произведение двух ма
т-
риц
A
=[
a
ij
] и
B
=[
b
jk
], где
i
=
1,
n
,
j
=
1,
m
,
k
=
1,
l
(*
). При вычислениях оп
е-
рация целочисленного умноже
ния заменяется конъюнкцией, а слож
е-
ние

дизъюнкцией; присваивание (=).

10. Создать производный класс «МИНОР» для базового класса
«МАТРИЦА» размерности
n

m
. Переопределить для производного
класса оп
е
рации и
методы (см. лаб. работу № 2, за
дание № 4).

11. Расширить возможности стандартного класса
Time
, чт
о
бы
можно б
ы
ло выводить время дня: утро, вечер и т. д.

12. Расширить возможности стандартного класса
Date
, чтобы
можно было выводить время года: зима, лето и
т. д.

13. Расширить возможности класса
Annotation
, чтобы можно было
выводить время и дату изменения аннотации.

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

15. Расширить возможности класса
Fil
e
, чтобы можно было выв
о-
дить время и дату создания файла.

16. Расширить возможности класса
Stack
, чтобы можно было в
ы-
водить время последнего сеанса работы со стеком.

17. Определить базовый класс для работы с прямоугольными ма
т-
рицами, предусмотрев ввод
-
выво
д матриц и выполнение следующих
операций: сложение матриц; умножение матрицы на скаляр; перест
а-
новка строк матрицы по заданному вектору транспозиции; перест
а-
новка столбцов матрицы по заданному вектору транспозиции.
В пр
о-
изводном классе реализовать указанны
е оп
е
рации для квадратных
матриц, добавив выполнение сл
е
дующих операций:

транспонирование
матрицы; умножение ма
т
риц.

Тесты

1. Какая из записей является правильной записью абстрактного кла
с
са?

Варианты ответа:

1)
abstract

class

A

virtual

f
()=0;;

*2)
class

A

virtual

f
()=0;;

3)
class

A

virtual

f
();;


44

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

это класс, в котором:

1) есть хотя бы один виртуальный метод;

2) есть виртуальный конструктор;

3) есть виртуальный деструктор;

*4) есть чисто виртуальный метод.

3. Основная проблема множ
ественного наследования состоит в:

1) замедлении выполнения программ;

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

*3) возможности существования двух экземпляров объекта базового класса;

4) неэкономном расходовании памяти.

4
. Если записано

class Apublic:virtual void f()cout<<1;;

class B:public A public:virtual void f()cout<<2;;

то что будет напечатано, если

B b;A &a=b; a.f(); ?

Варианты ответа:

*1) 2; 2) 21; 3) 12; 4) 1; 5) ошибка.

5. Если записано

class A public:vo
id f()cout<<1;;

class B:public Apublic: void f()cout<<2;;

то что будет напечатано, если

B b; b.f(); ?

Варианты

ответа:

*1) 2; 2) 21; 3) 12; 4) 1.

6. Если

записано


class Apublic:virtual void f()cout<<1;;

class B:public Apublic:virtual void f()
cout<<2;;

то что будет напечатано, если

B b; b.f(); ?

Варианты ответа:

*1) 2; 2) 21; 3) 12; 4)1; 5)ошибка.

Лабораторная работа № 6

Тема. Потоки, обработка исключительных

с
и
туаций в
C
++

Теоретическое введение.
В С++ ввод
-
вывод осуществляется
через пото
ки. Потоки являются объектами соответствующих классов.
При запуске программы автоматически открываются стандартные
потоки
cin, cout, cerr, clog.
Последние два потока используются для
вывода сообщений об ошибках. В файле
iostream.h
определены
классы: ввода


istream
, вывода


ostream
, ввода
-
вывода


iostream
.


Для реализации файлового ввода
-
вывода небходимо включить
файл
fstream.h
, содержащий производные от
istream
и
ostream
классы
ifstream,

ofstream
и
fstream
,

и объявить соответствующие объекты.
Например:


45

i
fstream

in
;//ввод

ofstream

out
;//вывод

fstream io;//
ввод
-
вывод

После объявления потоков производится открытие файла,
связывающее его с потоком с помощью функции
open()
или с
помощью конструктора. Прототип

функции

open():

void open (char *filename,int mode,
int access);

Здесь
filename


имя файла, включающее путь;
mode


режим
открытия файла (
ios::in


открытие файла для чтения,
ios::out



открытие для записи,
ios::binary


открытие файла в двоичном
режиме, по умолчанию в текстовом);
access:
0

файл со свобо
дным
доступом, 1

только для чтения, 8

архивный файл. Файл
закрывается с помощью функции
close().


Для чтения
-
записи здесь можно использовать перегружаемые
оператор
-
функции >> и << или использовать методы классов. Для
ввода
-
вывода одного символа исполь
зуются функции:

istream &get(char &ch); ostream &put(char ch);

Для записи и считывания блоков двоичных данных используются
функции считывания
-
записи
n
байт в буфер или из буфера:

istream &read(unsigned char *buf, int n);

ostream &write(const unsigned char
*buf, int n);

Обработка исключительных ситуаций.

В программах на С++ следует
использовать механизм обработки исключительных ситуаций. Опер
а-
торы программы при обработке исключительных ситуаций распол
а-
гаются в блоке
try
. Перехватывается и обрабатывается искл
ючител
ь-
ная ситуация в блоке
catch
. Форма операторов
try
-
catch
следующая:

try /*
блок
try*/



catch(type1 arg)/*
блок
catch*/


С блоком
try
может

связываться несколько блоков
catch
. Выпо
л-
няется тот блок
catch
, для которого тип аргумента соответствует типу

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

catch(…)

/*тело*/

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


46

тип имя (список аргументов) throw(список типов)

/*тело
*/


Пример.
Из текстового потока ввести информацию о студентах и
записать ее в виде дерева. Отсортировать или по фамилии, или по
баллу (вывести тех студентов, у которых балл выше среднего).
Использовать потоки ввода
-
вывода и шаблоны.

#
include
<
iostream
.
h
>

#
include
<
conio
.
h
>

#include

struct Student

int num;

char surname[10];

int group;

int balls;

friend ostream &operator<< (ostream &stream, Student stud)

stream << " " << stud.num << " " <<
stud.surname << " " << stud.group

<< " " << stud.balls;

return stream;



friend istream &operator>> (istream &stream, Student &stud)

stream >> stud.num >> stud.surname >> stud.group >> stud.
balls;

return stream;



;

struct node

Student info;

node *nextl, *nextr;

node ()

info.num = info.group = info.balls=0;

nextl = nextr = 0;



node (Student new
info)

info = newinfo;

nextl = nextr = 0;



;

template class tree

public:

T *root;

tree()  root = 0; 

void push (T *& wer, T1 dat, int n)

if (w
er == 0)

try

wer = new T;

if(!wer) throw 1;

wer
-
>nextl = 0; wer
-
>nextr = 0; wer
-
>info = dat;


47



catch (in
t mthrow) cout<<”No memory!”<


else if (n == 1)

if (strcmp(dat.surname,wer
-
>info.surname) < 0) push (wer
-
>nextl, dat, 1);

else push (wer
-
>nextr, dat, 1);

else

if (dat.balls > wer
-
>info.balls) push (wer
-
>nextl, dat, 2);

else push (wer
-
>nextr, dat, 2);



void insert (T1 dat, int n)

if (root == 0) root = new T(dat); else push (root, da
t, n);



void look (ostream &stream, T *&wer)

if (wer != 0)

look (stream, wer
-
>nextl);

stream << " " << wer
-
>info << endl;

look (stream, wer
-
>nextr);





friend ostream &operator<< (ostream &stream, tree ob)

 ob.look (stream, ob.root); return stream; 

;

void main()

int m;

do

cout << "1. Sort with names
\
n";

cout << "2. Sort with balls
\
n";

cou
t << "3. Exit
\
n";

cin >> m;

switch (m)

case 1: 

tree q;

node *n;

ifstream infile("stud.txt");

while(!infile.eof())


Student c;

infile >> c;

q.insert(c, 1);



infile.close();

cout<
break;



case 2:


tree q;

node *n;


48

ifstream infile("stud.txt");

Student *c;

c = new Student;

int i = 1;

float s = 0;

whi
le(!infile.eof())

infile >> c[i];

s+=c[i].balls;

i++;



for (int j=1; j<=i; j++)

if (c[j].ba
lls > s/i)

q.insert(c[j], 2);

infile.close();

cprintf(" Miide ball is %1.3f",s/i);

cout<<'
\
n' << q;

break;



case 3: return;

default: cout<<"Error! Try again
\
n"; break;



getch();

clrscr
(); 


while
(
m
!= 3);

return;

Задания для самостоятельного решения

При выполнении приводимых ниже заданий можно использовать
классы, разработанные в лабораторных
работах № 1

3. Осуществлять
контроль состояния потоков. В случае возникновения ошибок потоков
генерировать и обрабатывать исключительные ситуации. Для соотве
т-
ствующих классов перегрузить операции вставки в поток и извлеч
е-
ния из потока. При динамическом вы
делении памяти предусмотреть
обр
а
ботку исключения, возникающего при нехватке памяти.

I

а) Для класса
Student
(лаб. работа № 1) предусмотреть ввод
данных из файла. Полученные при выполнении лаб. работы № 1 сп
и-
ски студе
н
тов вывести в файл.

То же задание для
классов:

б)
Abiturient
(лаб. работа №1);

в)
Aeroflot
(лаб. работа № 1);

г)
Worker
(лаб. работа № 1);

д)

Train

(лаб. работа № 1);

е)

Product
(лаб. работа № 1);


49

ж)

Patient

(лаб. работа № 1);

з)
Bus

(лаб. работа № 1);

и)
Customer
(лаб. работа № 1);

к)
File
(
лаб. работа № 1);

л)
Word
(лаб. работа № 1);

м)
House
(лаб. работа № 1);

н)
Phone
(лаб. работа № 1);

о)
Person
(лаб. работа № 1).

II

а) При выполнении задания № 1 лаб. работы № 2 (класс
Com
-
plex
) предусмотреть формирование массива объектов путем считыв
а-
ния
комплексных чисел из файла. Результат также в
ы
вести в файл.

То же задание для классов:

б)
Fraction
(лаб. работа № 2);

в)
Vector
(лаб. работа № 2). Предусмотреть обработку исключ
е-
ния при динамическом выделении памяти;

г)
Matrix
(лаб. работа № 2);

д)
Polyno
m
(лаб. работа № 2);

е)
Stack
(лаб. работа № 2);

ж)
Строка
(лаб. работа № 2);

з)
Set
(лаб. работа № 2);

и)
«Массив строк»
(зад. № 10 лаб. работы № 2);

к) «
Булев вектор»
(лаб. работа № 2);

л) «
Троичный вектор»
(лаб. работа № 2);

м) «
Булева матрица»
(лаб. ра
бота № 2).

III

Те же задания, что и в разделах
I
и
II
, но для классов, реал
и-
зующих работу с динамическими структурами данных (см. лаб. раб
о-
ту № 3).

Тесты

1. Если имеется код
char

a
[8];
cin
>>
a
; и вводится текст “
Hello

World
”, то
что б
у
дет в массиве
a
?

Вариа
нты

ответа
:

1) “Hello W”; 2) “Hello Wo”; *3) “Hello”; 4) “Hello World”; 5) “lo World”.

2. Что будет выведено в результате

double x=12.4;

cout<
Варианты ответа:

1) 12.40***; *2) 12.4***; 3) 12.4 ***; 4) 12.4
0; 5) .124
e
2***.

3. Если имеется код
int

x
;
cin
>>
x
; и вводится “1.2”, что будет в перемен
ной
x
?


50

Варианты ответа:

*1) 1; 2) 2; 3) 1.2; 3) другое; 4) произойдет ошибка.

4. Какой из классов используется для вывода строк на э
к
ран?

Варианты

ответа:

1) strstre
am; *2) ostream; 3) ofstream; 4) istream; 5) ifstream.

5. Каким будет результат работы программы:

#include

void main ()

char A[]=”ABC”;

char
*
U=&A[2];

cout<<”
\
n”<<
*
U
--
<<
*
U
--
<<
*
U<
Варианты ответа:

1)
BAA
; *2)
CBA
.

6. Если имеется код

double

x
;
cin
>>
x
; и вводится “12
-
3”, то что бу
дет в п
е
-
ре
менной
x
?

Варианты ответа:

1) 9.0; *2) 12.0; 3) другое; 4) произойдет ошибка.

7. Для того, чтобы выполнить чтение из файла с произвольной по
зиции,
надо использовать объект класса:

1) strstream; 2
) ostream; 3) ofstream; 4) istream; *5) ifstream.

8. Что будет выведено при выполнении оператора
throw

C
, если заданы
классы

class A …;

class B: public A …;

class C: public A …;

а обработка исключительной ситуации записана

catch (B&b) cout<<1;

cat
ch (C&c) cout<<2;

catch (A&a) cout<<3;

catch (…)

cout
<<4;
?

Варианты ответа:

1) 1; *2) 2; 3) 3; 4) 4; 5) 34; 6) 234.

9. Если в конструкторе класса

class

A


char
*
ptr
;

public
:

A
() 
ptr
=
new

char
[
size
];
Init
();

~
A
() 
if
(
ptr
)
delete
[]
ptr
;

;

произойдет исключительная ситуация, будет ли потеряна память при откате по
стеку?

Варианты ответа:

1) да, будет во всех случаях; 2) будет, только если объект класса созда
вался
с помощью
new
; *3) будет, если создавалась автома
тическая пере
менная
класса
A
; 4) нет, не будет.

10. Об ошибке в конструкторе класса может сигнализировать:


51

1) возвращаемое значение; *2) исключительная ситуация; 3) вы
зов дес
т
-
руктора сразу в конструкторе.

11. Что будет выведено, если заданы классы

class

A
…;

class B: public A …
;

class C: public A …;

а операторы
throw
и
catch
записаны так:

throw A;

catch (B&b) cout<<1;

catch (C&c) cout<<2;

catch (A&a) cout<<3;

catch
(…) 
cout
<<4; ?

Варианты ответа:

1) 1; 2) 2; *3) 3; 4) 4; 5) 34; 6) 234.

12. Оператор
throw
без аргумен
тов

*1) повторно вызывает обрабатываемую исключительную с
и
туацию;

2) вызывает исключительную ситуацию типа
Exception
.

13. Что будет выведено, если заданы классы

class

A
…;

class B: public A …;

class C: public B …;

а операторы
throw
и
catch
записа
ны так:

throw

C
;

catch (B&b) cout<<1;

catch (C&c) cout<<2;

catch (A&a) cout<<3;

catch (…)

cout
<<4;
?

Варианты ответа:

*1) 1; 2) 2; 3) 3; 4) 4; 5) 1234; 6) 234.


ЛИТЕРАТУРА

1.

Страуструп, Б.
Язык программирования С++/
Б. Страуструп.

СПб.:БИНОМ, 1999.

2.

Ш
илдт, Г
. Самоучитель С++/
Г. Шилдт
. 3
-
е изд. СПб.:
BXV
-
Петербург,
2002.

3.

Эккель, Б.
Философия С++. Введение в стандартный С++/
Б. Эккель.
2
-
е и
з-
д. СПб.:Питер, 2004.

4.

Эккель, Б.
Философия С++. Практическое программирование/
Б. Эккель, Ч.
Эллисон .
СПб.:Питер, 200
4.

5.

Павловская, Т.А.
С++. Объектно
-
ориентированное программ
и
ро
вание:
Практикум/
Т. А. Павловская,

Ю. А. Щупак.
СПб.:Питер, 2004.

6.

Глушаков, С.В.
Язык программирования С++/
С. В. Глушаков, А. В. Коваль,
С. В. Смирнов.
Хар
ь
ков:Фолио, 2002.

7.

Фридман, А. Л.
Язык
программирования С++. Курс лекций/
А. Л. Фридман.

М.:ИНТУИТ, 2003.


52

СОДЕРЖАНИЕ

Л
АБОРАТОРНАЯ РАБОТА


1.

Т
ЕМА
.

П
РОСТЕЙШИЕ КЛАССЫ И
ОБЪЕКТЫ
................................
................................
.................
3

Л
АБОРАТОРНАЯ РАБОТА


2

Т
ЕМА
.

Р
АЗРАБОТКА КЛАССОВ
................
9

Л
АБОРАТОРНАЯ РАБОТА


3.

Т
ЕМА
.

К
ЛАССЫ ДЛЯ РАБОТЫ С
ДИНАМИЧЕСКИМИ СТРУКТ
УРАМИ ДАННЫХ
...............................
19

Л
АБОРАТОРНАЯ РАБОТА


4.

Т
ЕМА
.

Ш
АБЛОНЫ КЛАССОВ
...............
26
6

Л
АБОРАТОРНАЯ РАБОТА


5.

Т
ЕМА
.

Н
АСЛЕДОВАНИЕ
.....................
33
3

Л
АБОРАТОРНАЯ РАБОТА


6.

Т
ЕМА
.

П
ОТОКИ
,
ОБРАБОТКА
ИСКЛЮЧИТЕЛЬНЫХ СИТУ
АЦИЙ В
C
++
................................
..
44
4


53








Учебное издание


Романчик Валерий Станиславович

Люлькин Аркадий Ефимович


С++. ЛАБОРАТОРНЫЕ РАБОТЫ

по курсу
«Методы программирования»




Учебно
-
методическое пособие

для студентов механико
-
математического

факультета




Технический редактор
__

Корректор


Ответственный за выпуск
В. В. Власова


Подписано в печать __.__.2005. Формат 60х84/16. Бумага офсетная. Пе
чать офсе
т
ная.

Усл.печ.л. ____. Уч.
-
изд.л. . Тираж 100 экз. Зак.


Белорусский государственный университет.

Лицензия ЛВ №315 от 14.07.98.

220050, Минск, пр. Ф. Скорины,4.


Отпечатано в издательском центре БГУ.

220030, Минск, ул. Красноармейская, 6
.



Приложенные файлы

  • pdf 1046970
    Размер файла: 665 kB Загрузок: 0

Добавить комментарий