Полный текст:
ОГЛАВЛЕНИЕ
1.Введение:
Объектно-ориентированное программирование. 3
2. Постановка задачи. 5
Алгоритм решения задачы.. 5
3. Ход реализации. 7
Модульная структура программы.. 7
Код программы: содержание
отдельных модулов. 8
4. Тестирование проекта. 19
Список литературы.. 25
1.Введение: Объектно-ориентированное программирование
Объектно-ориентированное
программирование — это методология программирования, которая основана на
представлении программы в виде совокупности объектов, каждый из которых
является реализацией определенного класса (типа особого вида).
Несмотря на то что в
различных источниках делается акцент на те или иные особенности внедрения и
применения ООП, три основных (базовых) понятия ООП остаются неизменными. К ним
относятся:
• наследование
(Inheritance);
• инкапсуляция
(Encapsulation);
• полиморфизм
(Polymorphism).
При процедурном подходе
требуется описать каждый шаг, каждое действие алгоритма для достижения
конечного результата. В отличие от него объектно-ориентированный подход
оставляет за объектом право решать, как отреагировать и что сделать в ответ на
поступивший вызов. Объект состоит из следующих трех частей:
• имени объекта;
• состояния (переменных
состояния);
• методов (операций).
Можно дать обобщающее
определение: объект ООП— это совокупность переменных состояния и связанных с
ними методов (операций). Упомянутые
методы определяют, как объект взаимодействует с окружающим миром.
Под методами объекта
понимают процедуры и функции, объявление которых включено в описание объекта и
которые выполняют действия. Возможность управлять состояниями объекта
посредством вызова методов в итоге и определяет поведение объекта. Совокупность
методов часто называют интерфейсом объекта.
Инкапсуляция — это
механизм, который объединяет данные и методы, манипулирующие этими данными, и
защищает и то и другое от внешнего вмешательства или неправильного
использования. Когда методы и данные объединяются таким способом, создается
объект.
Применяя инкапсуляцию, мы
защищаем данные, принадлежащие объекту, от возможных ошибок, которые могут
возникнуть при прямом доступе к этим данным. Кроме того, применение указанного
принципа очень часто помогает локализовать возможные ошибки в коде программы. А
это намного упрощает процесс поиска и исправления этих ошибок. Можно сказать,
что инкапсуляция обеспечивает сокрытие данных, что позволяет защитить эти
данные.
Наследование — это
процесс, посредством которого один объект может наследовать свойства другого
объекта и добавлять к ним черты, характерные только для него. В итоге создается
иерархия объектных типов, где поля данных и методов «предков» автоматически
являются и полями данных и методов «потомков».
Смысл и универсальность
наследования заключаются в том, что не надо каждый раз заново («с нуля»)
описывать новый объект, а можно указать «родителя» (базовый класс) и описать
отличительные особенности нового класса. В результате новый объект будет
обладать всеми свойствами родительского класса плюс своими собственными
отличительными особенностями.
Полиморфизм — это свойство,
которое позволяет одно и то же имя использовать для решения нескольких
технически разных задач. Полиморфизм подразумевает такое определение методов в
иерархии типов, при котором метод с одним именем может применяться к различным
родственным объектам. В общем смысле концепцией полиморфизма является идея
«один интерфейс — множество методов». Преимуществом полиморфизма является то,
что он помогает снижать сложность программ, разрешая использование одного
интерфейса для единого класса действий. Выбор конкретного действия в
зависимости от ситуации возлагается на компилятор.
2.
Постановка задачи
Написать программу,
которая моделирует проведения спортивных состязаний между клубными командами.
Предполагается, что N команд встречаются между собой дважды, причем это можно
отобразить в виде прямоугольной матрицы(NxN). Программа должна запрашивать результаты,
заносить их в таблицу, и, в результате, выводить текущее положение команд по
ранжиру согласно максимальной сумме набранных очков".
Алгоритм решения задачы состоит из следующих основных частей:
введение число клубных команд,введение имен клубных команд,введение результатов всех игр,вычисление набранных очков для каждой
команды,упорядочение команд по максимальной
сумме набранных очков (получeние турнирной таблицы),вывод турнирной таблицы.
В проекте разработаны 3
классы – club(клубная команда), score (счет игры), matches (матчы: спортивные состязания между n клубными командами).
На рисунке 1 представлены взаимодействия этих трех классов и структура класса matches, a все поля и методы классов подробно
описаны в разделе «Ход реализации».
Рисунок 1
3. Ход реализации
Модульная структура программы
Рисунок 2
В проекте реализована
следующая модульная структура программы (Рисунок 2):
club.h – модуль, реализующий класс club
(клубная команда);score.h, score.cpp – модуль, реализующий класс score (счет игры);matches.h, matches.cpp – модуль, реализующий класс matches (матчы: спортивные состязания между n клубными командами);main.cpp – модуль для
тестирования программы.
Код
программы: содержание отдельных модулов
Рисунок 3
Класс club (файл club.h):
#ifndef
CLUB_H
#define
CLUB_H
#include
<iostream.h>
typedef
char string [80];
class
club{
protected:
string name; //имя клубной
команды, максимум 80
символы
public:
void insert(){cin>>name;} //ввод имени
void print(){cout<<name;} //вывод
имени
};
#endif
Класс score (файл score.h):
#ifndef
SCORE_H
#define
SCORE_H
#include
<iostream.h>
class
score {
int p1,p2; //счет игры: p1 количество забитых голов первой
команды,
//p2 количество забитых голов второй команды
public:
score (int=0,int =0); // конструктор
void insert(){cin>>p1>>p2;}
//ввод счета
int get_point_club_1(); //набранное очко
первой команды
int get_point_club_2(); // набраное очко второй команды
void
print(){cout<<p1<<":"<<p2<<endl;}//вывод счета
};
#endif
Класс score (файл score.cpp):
#include
"score.h"
score::score(int
t1, int t2)
{
p1=(t1>0)?t1:0;
p2=(t2>0)?t2:0;
}
int
score::get_point_club_1()
{
if(p1>p2)
return 3;
if(p1 == p2)
return 1;
return 0;
}
int
score::get_point_club_2()
{
if(p2>p1)
return 3;
if(p1 == p2)
return 1;
return 0;
}
Kонструктор сначала
проверяет значения
входных параметров t1 и t2, если они положительные числа, то присваиваются
полям p1 и p2, а в противном
случае присваеваются нули.
Mетод get_point_club_1()
возврощает набранное очко первой команды: 3 – в случае выигриша, 1– в случае
ничьи, 0 – в случае проигрыша.
Аналогичным образом метод get_point_club_2() возврощает
набранное очко второй
команды.
Класс matches (файл matches.h):
#ifndef
MATCHES_H
#define
MATCHES_H
#include
"club.h"
#include
"score.h"
#include
<assert.h>
class
matches{
int n;
club *clubs;
score **a;
int ** standings;
public:
matches (int=2);
~matches ();
void insert();
void print();
void sort();
int get_max_index(int);
};
#endif
Класс matches имеет
следующие поля:
n – количество
спортивных клубов,clubs – массив спортивных клубов (массив объектов класса club),a – матрица счетов всех матчов состязании (квадратная матрица объектов класса score), элемент a[i][j] представляет собой счет матча клубов clubs[i] – clubs[j], a элемент
a[j][i]
представляет собой счет
матча clubs[j] –
clubs[i],standings –
турнирная таблица: двумерный целочисленный массив, первая строка которого
предназначена для хранения набранных очков, а вторая строка – для номера
спортивной команды. На первый взгляд вторая строка лищная, но его необходимость
возникает во время сортировки турнирной таблицы, когда нужно запоминать номер
клуба в процессе перестановки очков.
Класс matches (файл matches.cpp):
#include
"matches.h"
#include
"matches.h"
#include
<iostream.h>
matches::matches(
int n1)
{
n=(n1>2)?n1:2;
clubs = new club[n];
assert(clubs);
a = new score * [n];
assert(a);
standings = new int* [2];
assert(standings);
for(int i=0;i<2;i++){
standings[i]=new int [n];
assert(standings[i]);
}
for (i=0;i<n;i++)
{
a[i]= new score [n];
assert(a[i]);
standings[0][i]=0;
standings[1][i]=i;
}
}
matches::~matches
()
{
delete [] clubs;
for(int i=0;i<n;i++)
delete []a[i];
delete a;
for(i=0;i<2;i++)
delete []standings[i];
delete standings;
}
void
matches::insert ()
{
cout<<"Insert names of
"<<n<<" commands"<<endl;
for(int i=0;i<n;i++)
clubs[i].insert();
for(i=0;i<n;i++)
for(int j=i+1;j<n;j++){
cout<<"Insert
rezult of the game ";
clubs[i].print ();
cout<<" - ";
clubs[j].print ();
cout<<endl;
a[i][j].insert();
standings[0][i]+=a[i][j].get_point_club_1();
standings[0][j]+=a[i][j].get_point_club_2();
cout<<"Insert rezult of the game ";
clubs[j].print ();
cout<<" - ";
clubs[i].print ();
cout<<endl;
a[j][i].insert();
standings[0][j]+=a[j][i].get_point_club_1();
standings[0][i]+=a[j][i].get_point_club_2();
}
sort();
}
void
matches::print ()
{
cout<<endl<<"There are
scores:"<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
{
if(i==j) continue;
clubs[i].print();
cout<<" -
";
clubs[j].print();
cout<<" ";
a[i][j].print();
}
}
cout<<endl<<"There are
standings:"<<endl;
for(i=0;i<n;i++){
clubs[standings[1][i]].print();
cout<<" "<<standings[0][i]<<endl;
}
cout<<endl;
}
int
matches::get_max_index(int k)
{
int max_index =k;
for(int i=k+1;i<n;i++)
if(standings[0][i]>standings[0][max_index])
max_index=i;
return max_index;
}
void
matches::sort()
{
for(int i=0;i<n;i++)
{
int
max_index=get_max_index(i);
int temp=standings[0][i];
standings[0][i]=standings[0][max_index];
standings[0][max_index]=temp;
temp=standings[1][i];
standings[1][i]=standings[1][max_index];
standings[1][max_index]=temp;
}
}
Конструктор
класса matches создает объект следующим образом:
сначала проверяет значение целочисленного входного
параметра n1, и если оно больше или равно двум, то
присваиваются полю n
(числу спортивных клубов),
а в противном случае значение поля n равняется двум, поскольку для соревнования нужны по крайней
мере 2 команды;
создается
динамический массив
спортивных клубов clubs из n объектов класса club,
проверяется была ли уделина память;
создается турнирная таблица standings, первая
строка которого потом инициализуется нулями, то есть набранные очки всех команд
равняются нулям, а каждый элемент standings[1][i] равняется i;
создается
матрица a,
которая представляет собой n мерный массив, каждая из эелементов которого представляет n мерный массив объектов класса score, то есть каждый эелемент a[i][j] матрицы a представляет собой счет игры клубов clubs[i] и clubs[j].
Деструктор класса
matches
поочередно освобождает
памяти, выделенных для полей clubs, a, standings.
Метод insert() класса matches обеспечывает ввод данных и вычисление набранных очков
следующим образом:
Выводит на экран текст, который подсказывает пользователя
вводить имена n спортивных
клубов,
С помощью функции insert() класса club вводит имена всех n спортивных клубов,
Запрашивает и вводит результаты игр
всех пар спортивных команд,
после ввода очередного элемента a[i][j] результата игры спортивных
команд club[i] и club[j],
с помощью функций
get_point_club_1() и get_point_club_2() класса score вычисляются
набранные очки для обеих команд и добавляются к уже имеющихся очкам, таким образом в
процессе ввода поочередно строится и турнирная таблица– двумерный массив standings,
вызывается функция sort() класса matches, которая упорядочивает турнирную
таблицу в убывающем порядке.
Таким образом функция insert()
не только обеспечивает ввод входных
параметров, но и вычисляет и упорядочивает матрицу standings.
Функция print() класса matches
обеспечивает вывод результатов игр и турнирной таблицы следующим образом:
с помощью функций print() классов score и club выводит
результаты всех матчей в следующем
формате: имя первого клуба, тире, имя второго клуба, счет игры (Динамо – Спартак 0:4),
с
помощью функции print() класса club и второй строке матрицы standings
выводит турнирную таблицу.
Метод get_max_index(int k) класса matches
используется в функции sort() и возвращает индекс максимального эелемента в массиве standings[0], которая
находится после индекса k, следующим образом:
переменному max_index присваивается значение
парамтера k, то есть на первом шаге максимальный эелемент и есть элемент с индексом k,поочередно рассматриваются элементы
массива standings[0] начиная с индекса k+1, если очередной рассматриваемый
элемент standings[0][i] больше чем standings[0][max_index] то переменной
max_index присваивается
значение i,
возвращается
значение max_index.
Метод sort()класса matches упорядочивает турнирную таблицу в убывающем порядке,
следующим образом:
поочередно рассматриваются все
элементы массива standings[0]–набранные очки спортивных клубов,
в массиве standings[0] каждый элемент
индекса i меняется местами с эелементом индекса get_max_index(i),
то же самое делается в массиве
standings[1], то есть набранные очки перестановятся вместе с номерами клубов.
Перестановка выполняется с помощью локального переменного и функции get_max_index();
4.
Тестирование проекта
Для тестирования проекта, созданных
классов использована следующая программа.
(файл test.cpp)
#include
"matches.h"
void
main()
{
int n;
cout<<"Insert count of
clubs"<<endl;
cin>>n;
matches m(n);
m.insert ();
m.print
();
}
Программа
запрашивает число футбольных клубов, который вводится в переменную n. Затем
объявляется состязание m, между n футбольными командами.Осуществляется сначала ввод, потом вывод состязания m.
Пример тестирования проекта для состязаний между пятью командами.
Insert count of clubs
5
Insert names of 5 commands
Real
Barselona
Arsenal
Milan
Roma
Insert rezult of the game Real - Barselona
3
3
Insert rezult of the game Barselona - Real
2
2
Insert rezult of the game Real - Arsenal
2
1
Insert rezult of the game Arsenal - Real
2
1
Insert rezult of the game Real - Milan
2
0
Insert rezult of the game Milan - Real
1
2
Insert rezult of the game Real - Roma
3
0
Insert rezult of the game Roma - Real
2
2
Insert rezult of the game Barselona - Arsenal
1
0
Insert rezult of the game Arsenal - Barselona
1
0
Insert rezult of the game Barselona - Milan
3
1
Insert rezult of the game Milan - Barselona
0
0
Insert rezult of the game Barselona - Roma
4
1
Insert rezult of the game Roma - Barselona
3
3
Insert rezult of the game Arsenal - Milan
2
1
Insert rezult of the game Milan - Arsenal
0
1
Insert rezult of the game Arsenal - Roma
3
0
Insert rezult of the game Roma - Arsenal
2
2
Insert rezult of the game Milan - Roma
1
0
Insert rezult of the game Roma - Milan
1
1
There are scores:
Real - Barselona 3:3
Real - Arsenal 2:1
Real - Milan 2:0
Real - Roma 3:0
Barselona - Real 2:2
Barselona - Arsenal 1:0
Barselona - Milan 3:1
Barselona - Roma 4:1
Arsenal - Real 2:1
Arsenal - Barselona 1:0
Arsenal - Milan 2:1
Arsenal - Roma 3:0
Milan - Real 1:2
Milan - Barselona 0:0
Milan - Arsenal 0:1
Milan - Roma 1:0
Roma - Real 2:2
Roma - Barselona 3:3
Roma - Arsenal 2:2
Roma - Milan 1:1
There are standings:
Arsenal 16
Real 15
Barselona 13
Milan 5
Roma 4
Press any key to continue
Пример тестирования проекта для состязаний между тремя
командами (Рисунок 4)
Рисунок 4
Пример тестирования проекта для состязаний между четырьмя
командами (Рисунок 5)
Рисунок 5
Список литературы
Х.
Дейтел, П. Дейтел. Как программировать на C++: Пер. с англ. - Москва: ЗАО
"Издательство БИНОМ", 2008.
1454с.М.
Эллис, Б. Строуструп. Справочное руководство по языку C++ с комментариями: Пер.
с англ. - Москва: Мир, 1992. 445с. Карпов Б., Баранова Т. С++. Специальный
справочник (2-е издание). — СПб.: Питер, 2005. — 381с.: ил.Франка
П. С++: Учебный курс. — СПб.: Питер, 2005. — 522с.: ил.