Скачиваний:
52
Добавлен:
01.05.2014
Размер:
246.27 Кб
Скачать
  1. Проектирование конструкторов и деструкторов классов.

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

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

  1. Разработка методики тестирования классов и тестовых наборов данных.

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

  1. Зарегистрировать клиента - Ошибка

  2. Создать клиента №1 – Выполнено

  3. Отправить сообщение от клиента 1 клиенту 2 - Ошибка

  4. Зарегистрировать клиента 1 – Выполнено

  5. Отправить сообщение от клиента 1 клиенту 2 - Ошибка

  6. Создать клиента 2 – Выполнено

  7. Зарегистрировать клиента 2 – Выполнено

  8. Отправить сообщение от клиента 1 клиенту 2 – Выполнено

  9. Отправить сообщение от клиента 1 всем – Выполнено

  1. Выводы

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

Достоинство программы:

  • Решает поставленную задачу

  • Корректно работает на всех предложенных контрольных примерах

  • Имеет удобный интерфейс.

  • Говорящие конструкторы и деструкторы

Недостатков в программе не обнаружено.

  1. Сценарий диалога с пользователем

Структура основного меню:

  • Создать нового клиента

  • Зарегистрировать клиента на сервере

  • Послать кообщение одниму из клиентов

  • Послать сообщеине всем клиентам

  • Список клиентов

  • Выйти из программы

Меню выводится циклически, т.е. появляется после выполнения каждой операции.

  1. Количественные характеристики программы

Общая длина текста программы (в строках): 840. Из них:

Количество строк новых классов: 696

Количество строк тестирующей программы: 144

Общее количество классов, используемых в программе: 5

Количество новых (разработанных при выполнении работы) классов: 5

Общее количество заголовочных файлов: 5

Общее количество файлов-кодов: 6

Всего файлов: 11

Перечень имен новых классов:

Имя класса

Длина текста (в строках) описания класса

Общее количество функций класса, описанных вне класса

CServer

37

7

CClient

36

9

CMsg

31

5

CSrvList

32

11

CSrvItem

25

6

  1. Текст программы

//Файл: Main.cpp

//Реализация почтовой системы средствами ООП

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include<stdio.h>

#include "Client.cpp"

void main()

{

int choice; //choice - переменная выбора пункта меню

// clrscr();

printf ("Реализация почтовой системы средствами ООП\n");

printf ("Автор: Сергеев М.В. гр.3352\n");

printf ("Дата: 21.05.06, Редакция: 1.0\n");

printf ("\n Создание нового сервера и списка клиентов\n");

// CView L; //создание нового вида

CServer* s = new CServer();

CSrvList* clients = new CSrvList();

getch();

do //цикл меню

{

clrscr();

printf ("\n");

printf ("Создать нового клиента.......................1\n");

printf ("Зарегистрировать клиента на сервере..........2\n");

printf ("Послать кообщение одниму из клиентов.........3\n");

printf ("Послать сообщеине всем клиентам..............4\n");

printf ("Список клиентов..............................5\n");

printf ("Выйти из программы...........................0\n");

printf ("Ваш выбор");

scanf("%d",&choice);

printf ("\n");

switch(choice) //выбор пункта меню

{

case 1: //

{

clients->insertItem(new CClient());

printf ("\n");

getch();

}

break;

case 2: //

{

int c;

cout<<"\n\nClient ID:";

cin>>c;

CClient* cl = clients->getClientByID(c);

if(cl == NULL)

{

cout<<"\nТакого клиента не существует";

}

else

{

int res = cl->regOnSrv(s);

cout<<"\nКлиент зарегистрирован. Результат:"<<res<<".";

}

printf ("\n");

getch();

}

break;

case 3: //

{

int from,to,c;

cout<<"\n\nClient ID:";

cin>>from;

CClient* cl = clients->getClientByID(from);

if(cl == NULL)

{

cout<<"\nТакого клиента не существует";

}

else

{

cout<<"\nID клиента получателя:";

cin>>to;

cout<<"\nMessage(число):";

cin>>c;

int res = cl->sendMsg(c,s,to);

cout << "\nСообщение отправлено. Результат"<<res;

}

printf ("\n");

getch();

}

break;

case 4: //

{

int from,c;

cout<<"\n\nClient ID:";

cin>>from;

CClient* cl = clients->getClientByID(from);

if(cl == NULL)

{

cout<<"\nТакого клиента не существует";

}

else

{

cout<<"\nMessage(число):";

cin>>c;

int res = cl->sendMsgAll(c,s);

cout << "\nСообщение отправлено всем клиентам. Результат"<<res<<".";

}

printf ("\n");

getch();

}

break;

case 5: //

{

printf ("\n\nКлиенты:");

clients->show();

printf ("\n");

getch();

}

break;

} //switch

} while(choice!=0);

clients->resetNextClient();

do{

CClient* c = clients->getCurClient();

delete c;

}while(clients->hasNextClient());

delete s;

getch();

}//main

//Файл: Server.h

//Класс "Сервер". Прототип.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#ifndef ServerH

#define ServerH

#include "Client.h"

//#include "SrvList.h"

#include "SrvList.cpp"

#include "Message.h"

class CClient;

class CServer

{

private:

CSrvList* clients; //registered clients

static int nextID;

const int id;

static int count;

public:

int regCl(CClient*); //register clients on server

int resend(CMsg*); //resend msg from registred user to registred user

int resendAll(CClient* from, int comm);

CServer(); //constructor

~CServer();//destructor

void show()const; //show info

int getID()const;

};

int CServer::nextID = 0;

int CServer::count = 0;

#endif

//Файл: Server.cpp

//Класс "Сервер". Реализация.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include "Server.h"

////////////////////////////////////////////////////////////////

/*

register client on server

0-registered

1-bad

*/

int CServer::regCl(CClient*c)

{

if(c==NULL)

{

cout<<"\nServer: Не верная ссылка на клиент";

return 1;

}

cout << "\nServer: Client(id "<<c->getID()<<")";

CClient* cl = clients->getClientByID(c->getID());

if(cl != NULL)

{

cout<<" Уже был зарегистрирован";

return 1;

}

clients->insertItem(c);

cout <<" Успешно зарегистрирован";

return 0;

};

////////////////////////////////////////////////////////////////

/*

send msg to reciver

0 - client read msg

1 - client not read msg

2 - client(reciver) not registred

3 - client(sender) not registred

*/

int CServer::resend(CMsg* m)

{

cout<<"\nServer: преслал ";

m->show();

CClient* c = clients->getClientByID(m->getFrom());

if(c == NULL)

{

cout <<"\nServer: Client(id "<<m->getFrom()<<")- не зарегистрирован(отправитель)";

return 3;

}

c = clients->getClientByID(m->getTo());

if(c == NULL)

{

cout <<"\nServer: Client(id "<<m->getTo()<<") - не зарегистрирован(получатель)";

return 2;

}

int res = c->readMsg(m);

if(res == 0 )

{

cout <<"\nServer: Client(id "<<m->getTo()<<") прочел сообщение";

m->show();

return 0;

}

cout <<"\nServer: Client(id "<<m->getTo()<<") не прочел сообщение";

m->show();

return 1;

}

////////////////////////////////////////////////////////////////

/*

send msg to all clients

-1 - not registred

0 -ok

>0 - how many not got message

*/

int CServer::resendAll(CClient* from, int comm)

{

cout<<"\n\nServer: Отсылается сообщение с командой "<<comm;

cout<<" всем клиентам от \n Client(id "<< from->getID()<<")";

CClient* c = clients->getClientByID(from->getID());

if(c == NULL)

{

cout <<"\nSServer: Client(id "<<from->getID()<<")- не зарегистрирован(отправитель)";

return -1;

}

clients->resetNextClient();

int res = 0, numCl = 0;

do{

CClient* c = clients->getCurClient();

CMsg* m = new CMsg(from->getID(),c->getID(),comm);

res += c->readMsg(m);

numCl++;

}while(clients->hasNextClient());

cout<<"\nServer: послал сообщение "<<numCl<<" клиентам. Из них не получили его "<<res;

return res;

}

////////////////////////////////////////////////////////////////

/*

Constructor

*/

CServer::CServer():id(nextID++)

{

count++;

clients = new CSrvList();

cout<<"\n>Server";

};

////////////////////////////////////////////////////////////////

/*

Destructor

*/

CServer::~CServer()

{

count--;

clients->clear();

cout<<"\n>~Server";

};

////////////////////////////////////////////////////////////////

/*

show info

*/

void CServer::show()const

{

cout<<"\nЗарегистрированные клиенты:";

clients->show();

}

////////////////////////////////////////////////////////////////

/*

get server id

*/

int CServer::getID()const

{

return id;

}

//Файл: Client.h

//Класс "Клиент". Прототип.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include "Message.h"

#include "Server.h"

#ifndef CClientH

#define CClientH

class CServer;

class CClient

{

private:

static int nextID;

const int id;

static int count;

public:

CClient(); //constructor

~CClient(); //destructor

int regOnSrv(CServer*s);//regiter on server

int readMsg(CMsg*m); //read message

int sendMsg(int com,CServer*s,int toID); //send msg to client #toID

int sendMsgAll(int com,CServer*s); //send msg to all client througth server

void show()const; //info

void showCInfo()const;

int getID()const; //getters

};

int CClient::nextID = 0;

int CClient::count = 0;

#endif

//Файл: Client.cpp

//Класс "Клиент". Реализация.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include "Client.h"

#include "Message.cpp"

#include "Server.cpp"

////////////////////////////////////////////////////////////////

/*

try to register on server

0-all right

1-bad

*/

int CClient::regOnSrv(CServer*s)

{

//cout<<"\nClient#"<<id<<" tries to reg on server #" << s->getID() << "...";

int res = s->regCl(this);

if(res == 0 )

{

cout<<"\nClient(id "<<id<<") зарегистрирован на Server(id "<<s->getID()<<")";

return 0;

}

cout<<"\nClient(id "<<id<<") не смог зарегистрироваться на Server(id "<<s->getID()

<<") Ошибка №"<<res;

return 1;

};

////////////////////////////////////////////////////////////////

/*

read message

0-read ok

1-bad

*/

int CClient::readMsg(CMsg*m)

{

cout <<"\nClient(id "<<id<<") получил ";

m->show();

if(m->getTo() == this->id){

//message ok, executing command

cout <<" Комманда: "<<m->getCommand();

return 0;

}

cout <<"Сообщение не мое";

return 1;

};

////////////////////////////////////////////////////////////////

/*

send msg to client #toID

*/

int CClient::sendMsg(int comm,CServer*s,int toID)

{

CMsg* m = new CMsg(this->getID(),toID,comm);

cout <<"\nClient(id "<<this->getID()<<") отправил ";

m->show();

int res = s->resend(m);

if(res==0)

cout <<"\nClient(id "<<this->getID()<<") Сообщение доставлено";

else

cout <<"\nClient(id "<<this->getID()<<") Сервер вернул:"<<res;

return res;

};

////////////////////////////////////////////////////////////////

/*

send msg to all client througth server

*/

int CClient::sendMsgAll(int comm,CServer*s)

{

cout <<"\nClient(id "<<this->getID()<<"): отсылает всем клиентам команду:"<<comm;

int res = s->resendAll(this, comm);

if(res==0)

cout<<"\nClient(id "<<this->getID()<<"): все сообщения доставлены";

else

cout<<"\nClient(id "<<this->getID()<<"): Сервер вернул:"<<res;

return res;

}

////////////////////////////////////////////////////////////////

/*

Constructor

*/

CClient::CClient():id(nextID++)

{

count++;

cout <<"\n>Client(id "<<id<<")";

};

////////////////////////////////////////////////////////////////

/*

Destructor

*/

CClient::~CClient()

{

count--;

cout <<"\n>~Client(id "<<id<<")";

};

////////////////////////////////////////////////////////////////

/*

show info about client

*/

void CClient::show()const

{

cout<<"Client(id "<<id<<")";

}

////////////////////////////////////////////////////////////////

/*

Show info: how many clients avaliable

*/

void CClient::showCInfo()const

{

cout << "\nКоличество клиентов:" << count <<".";

}

////////////////////////////////////////////////////////////////

/*

getter for id

*/

int CClient::getID()const

{

return id;

}

//Файл: Message.h

//Класс "Сообщение". Прототип.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#ifndef MessageH

#define MessageH

class CMsg

{

private:

int const from; //id клиента

int const to; //id сервера

int const command; //команда

static int nextID;

const int id;

static int count;

public:

int getFrom(); //Возвращает поле from

int getTo(); //Возвращает поле to

int getCommand(); //Возвращает тело

void show()const; //Возвращает информацию о сообщении

CMsg(int f,int t,int c); //Конструктор

};

int CMsg::nextID = 1;

#endif

//Файл: Message.cpp

//Класс "Сообщение". Реализация.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include "Message.h"

////////////////////////////////////////////////////////////////

int CMsg::getFrom() //Возвращает поле from

{

return from;

};

////////////////////////////////////////////////////////////////

int CMsg::getTo() //Возвращает поле to

{

return to;

};

////////////////////////////////////////////////////////////////

int CMsg::getCommand() //Возвращает тело

{

return command;

};

////////////////////////////////////////////////////////////////

CMsg::CMsg(int f,int t,int c):from(f),to(t),command(c),id(nextID++) //Конструктор

{

cout <<"\n>Message(id:"<<id<<" From:"<<from<<" To:"<<to<<" Body:"<<command<<")";

};

////////////////////////////////////////////////////////////////

void CMsg::show()const //Возвращает информацию о сообщении

{

cout <<" Message(id:"<<id<<" From:"<<from<<" To:"<<to<<" Body:"<<command<<")";

}

//Файл: SrvList.h

//Класс "Список клиентов на сервере". Прототип.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include "SrvElem.cpp"

#include "Client.h"

#ifndef __SrvList_H

#define __SrvList_H

class CSrvList

{

private:

CSrvItem* first; //First element of the list

CSrvItem* cur; //current for iterator

public:

CSrvList(); //construcor

~CSrvList(); //destructor

int isEmpty(void)const; //Check if the list is empty(1-empty, 0-not empty)

void insertItem(CClient*); //insert new item into the list

void clear(); //clear this list

void show()const;

CClient* getClientByID(int);

CSrvItem* getFirstPtr(); //get pointer to the first element

int hasNextClient(); //iterator

CClient* getCurClient();

void resetNextClient();

};

#endif

//Файл: SrvList.cpp

//Класс "Список клиентов на сервере". Реализация.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include "SrvList.h"

#ifndef __SrvList_CPP

#define __SrvList_CPP

////////////////////////////////////////////////////////////////

/*

Constructor

*/

CSrvList::CSrvList():first(NULL)

{

cout <<"\n>CSrvList";

};

////////////////////////////////////////////////////////////////

/*

Destructor

*/

CSrvList::~CSrvList()

{

this->clear();

cout <<"\n>~CSrvList";

};

////////////////////////////////////////////////////////////////

/*

Check if the list is empty (1-empty, 0-not empty)

*/

int CSrvList::isEmpty(void) const

{

return (first == NULL)? 1 : 0;

};

////////////////////////////////////////////////////////////////

/*

Insert item into the list with value of problem part val

*/

void CSrvList::insertItem(CClient*n)

{

//adding value to the list

CSrvItem* newItem = new CSrvItem(n,NULL);

if(first == NULL){

first = newItem;

}else{

CSrvItem* tmp = first;

while(tmp->getNext() != NULL){tmp = tmp->getNext();}

tmp->setNext(newItem);

}

};

////////////////////////////////////////////////////////////////

/*

Clearing all the list

*/

void CSrvList::clear()

{

if(first == NULL)

{

cout <<"\nCSrvList: Список клиентов очищен";

return;

};

if(first->getNext() == NULL)

{

delete first;

first=NULL;

cout <<"\nCSrvList: Список клиентов очищен";

return;

}

CSrvItem *tmp,

*t;

tmp=first;

t=first->getNext();

while(t->getNext()!=NULL)

{

delete tmp;

tmp=t;

t=t->getNext();

}

delete tmp;

delete t;

first=NULL;

cout <<"\nCSrvList: Список клиентов очищен";

};

////////////////////////////////////////////////////////////////

/*

Show List on the screen

*/

void CSrvList::show() const

{

cout<<"\n>>>\n";

if(first == NULL){cout<<" Зарегистрированных клиентов нет.\n<<<\n";return;}

int number = 0;

CSrvItem *tmpPtr;//temporary pointer to move throught the list

tmpPtr = first; //starting from the begining

//moving till the end

while(tmpPtr->getNext() != NULL)

{

//printing the inf of the item and move forward

tmpPtr->getPoint()->show();

cout<<"\n";

tmpPtr=tmpPtr->getNext();

number++;

}

tmpPtr->getPoint()->show();

number++;

cout <<"\nВсего:"<<number<<"\n<<<\n";

};

////////////////////////////////////////////////////////////////

/*

return pointer to the first element

*/

CSrvItem* CSrvList::getFirstPtr()

{

return first;

};

/*

get registered client with ID= id

*/

CClient* CSrvList::getClientByID(int id)

{

if(first == NULL){

return NULL;

}else{

CSrvItem* tmp = first;

if(tmp->getPoint()->getID() == id)return tmp->getPoint();

while(tmp->getNext() != NULL){

tmp = tmp->getNext();

if(tmp->getPoint()->getID() == id)return tmp->getPoint();

}

// tmp->setNext(newItem);

if(tmp->getPoint()->getID() == id)return tmp->getPoint();

}

return NULL;

}

////////////////////////////////////////////////////////////////

/*

walk by all - iterator

*/

int CSrvList::hasNextClient()

{

if(cur == NULL)return 0;

cur = cur->getNext();

if(cur == NULL)return 0;

return 1;

}

CClient* CSrvList::getCurClient()

{

if(cur == NULL) return NULL;

return cur->getPoint();

}

void CSrvList::resetNextClient()

{

cur = first;

}

#endif

//Файл: SrvElem.h

//Класс "Элемент списка клиентов на сервере". Прототип.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include "Client.h"

#ifndef __SrvElem_H

#define __SrvElem_H

class CSrvItem

{

private:

CClient* clientPtr; //problem part

CSrvItem *nextPtr; //next item

public:

CSrvItem(CClient*, CSrvItem *n); //constructor, filling all params

~CSrvItem(); //destructor

CSrvItem* getNext()const; //getters

CClient* getPoint()const;

void setNext(CSrvItem*); //setters

void setPoint(CClient*);

};

#endif

//Файл: SrvElem.cpp

//Класс "Элемент списка клиентов на сервере". Реализация.

//Автор: Сергеев М.В. гр.3352

//Дата: 21.05.06, Редакция: 1.0

#include<iostream.h>

#include<conio.h>

#include "SrvElem.h"

#ifndef __SrvElem_CPP

#define __SrvElem_CPP

////////////////////////////////////////////////////////////////

CSrvItem* CSrvItem::getNext()const

{

return nextPtr;

};

////////////////////////////////////////////////////////////////

CClient* CSrvItem::getPoint()const

{

return clientPtr;

};

////////////////////////////////////////////////////////////////

void CSrvItem::setNext(CSrvItem*n)

{

nextPtr=n;

};

////////////////////////////////////////////////////////////////

void CSrvItem::setPoint(CClient*p)

{

clientPtr=p;

};

////////////////////////////////////////////////////////////////

/*

Constuctor

*/

CSrvItem::CSrvItem(CClient*c, CSrvItem *n)

{

clientPtr = c;

nextPtr = n;

cout <<"\n>CSrvItem(id "<<c->getID()<<")";

};

////////////////////////////////////////////////////////////////

/*

Destructor

*/

CSrvItem::~CSrvItem()

{

cout <<"\n>~CSrvItem";

};

#endif

18