Вы находитесь на странице: 1из 9

/*----------------------------------------------------------ex instructions are at the bottom files: main.cpp Menu.h , Menu.cpp Network.h , Network.cpp Message.h MsgResult.h MsgReqCalc.h Computer.

h Server.h Client.h ,

, ,

MsgResult.cpp MsgReqCalc.cpp

Computer.cpp , Server.cpp , Client.cpp

-----------------------------------------------------------*/

// main.cpp
#include <iostream> using namespace std; #include #include #include #include "Message.h" "Computer.h" "Network.h" "Menu.h"

// friends ostream& operator<<(ostream &os, const Message *m){ m->printDetails(); // polymorphism return os; } // operator<< to implement the use of cout<<message_pointer to print message data ostream& operator<<(ostream &os, const Computer *c){ c->printDetails(); // polymorphism return os; } // operator<< to implement the use of cout<<computer_pointer to print computer data // main int main(){ Network Menu

network menu(&network)

; ; ; ;

while(menu.doIt()) return 1 }

// Menu.h
// header of Menu class #ifndef MENU_INCLUDED_FLAG #define MENU_INCLUDED_FLAG #define #define #define #define ADD_COMPUTER SEND_MESSAGE PRINT EXIT 1 2 3 4

#include "Network.h" class Menu{ private: Network *network void addComputer() public: Menu(Network*) Int doIt() }; #endif

; ; ; ;

// Menu.cpp
// implementation of Menu class #include "Menu.h" #include "MsgReqCalc.h" #include <iostream> using namespace std; Menu::Menu(Network* _network):network(_network){ } // Menu(Network*), ctor that assigns the network pointer of the class void Menu::addComputer(){ char type; char name[80]; int capacity; cin>>type; cin>>name; if(type=='S') cin>>capacity; network->addComputer(type, name, capacity); } // addComputer(), add computer to network according to user input int Menu::doIt(){ int input; cin>>input; switch(input){ case ADD_COMPUTER: addComputer(); break; case SEND_MESSAGE: int param; cin>>param; network->sendMessage(new MsgReqCalc(param)); break; case PRINT: network->printComputers(); break; case EXIT: return 0; break; } return 1; } // doIt(), do an action according to the user input. returns 1 unless the input is 4 for exit

// Network.h
// header of Network class #ifndef NETWORK_INCLUDED_FLAG #define NETWORK_INCLUDED_FLAG #define MAX_COMP_NUM 20 #include "Computer.h" class Network{ private: Computer *computers[MAX_COMP_NUM] int length public: Network() void addComputer(char _type, char* _name, int capacity) void printComputers() const void sendMessage(Message* _message) const ~Network() }; #endif

; ; ; ; ; ; ;

// Network.cpp
// implementation of Network class #include "Network.h" #include "Server.h" #include "Client.h" #include "MsgReqCalc.h" #include "MsgResult.h" #include <iostream> using namespace std; Network::Network():length(0){ } // blank ctor, assigns length=0 void Network::addComputer(char _type,char* _name, int _capacity){ Computer *pcomp; if(_type=='C') pcomp=new Client(this,_name); else pcomp=new Server(this,_name,_capacity); computers[length++]=pcomp; } // addComputer(type,name,capicity), adds a new computer to the network by the params of the functions void Network::printComputers() const{ for(int i=0;i<length;i++) cout<<computers[i]<<endl; } // printComputers(), prints all computers in network void Network::sendMessage(Message* _message) const{ cout<<"* Sending "<<_message<<endl; for(int i=0;i<length;i++){ cout<<computers[i]<<": "; // polymorphism computers[i]->receiveMessage(_message); // polymorphism } cout<<"* Finish "<<_message<<endl; delete _message; } // sendMessage(Message*), sends message over the network and prints the message details Network::~Network(){ for(int i=0;i<length;i++) delete computers[i]; } // d'tor, deletes all computers

// Message.h
// header of Message class #ifndef MESSAGE_INCLUDED_FLAG #define MESSAGE_INCLUDED_FLAG #define MAX_CHARS 80 #include <iostream> using namespace std; class Message{ private: public: virtual void printDetails() const=0; friend ostream& operator<<(ostream &os, const Message *m); // this functions uses printDetails() (polymorphizm) virtual ~Message(){};// http://tiny.cc/kwrx3 - dtor has to be implemented (even blank one) }; #endif

// MsgResult.h
// header of MsgResult class #ifndef MSGRESULT_INCLUDED_FLAG #define MSGRESULT_INCLUDED_FLAG #define SOURCE_MAX_CHARS 20 #include "Message.h" class MsgResult:public Message{ private: int result char source[SOURCE_MAX_CHARS] public: MsgResult(const char *_source,int _result) virtual void printDetails() const int& getResult() char* getSource() // (no need for dtor) }; #endif

; ; ; ; ; ; ;

// MsgResult.cpp
// implementation of MsgResult class #include "MsgResult.h" #include "string.h" #include <iostream> using namespace std; MsgResult::MsgResult(const char *_source,int _result):result(_result){ strncpy(source,_source,SOURCE_MAX_CHARS); } // ctor, assigns the source and param void MsgResult::printDetails() const{ cout<<"(MsgResult, "<<source<<", "<<result<<")"; } // printDetails(), (virtual) prints the details of result message int& MsgResult::getResult(){ return result; } // getResult(), returns reference to param char* MsgResult::getSource(){ return source; } // getSource(), returns reference to param

// MsgReqCalc.h
// header of MsgReqCalc class #ifndef MSGREQCALC_INCLUDED_FLAG #define MSGREQCALC_INCLUDED_FLAG #include "Message.h" class MsgReqCalc:public Message{ private: int param public: MsgReqCalc(int _param) virtual void MsgReqCalc::printDetails() const int& getParam() // (no need for dtor) }; #endif

; ; ; ; ;

// MsgReqCalc.cpp
// implementation of MsgReqCalc class #include "MsgReqCalc.h" #include <iostream> MsgReqCalc::MsgReqCalc(int _param):param(_param){ } // ctor that assigns the param void MsgReqCalc::printDetails() const{ cout<<"(MsgReqCalc, "<<param<<")"; } // printDetails(), (virtual) prints the details of request message int& MsgReqCalc::getParam(){ return param; } // getParam(), returns reference to param

// Computer.h
// header of Computer class #ifndef COMPUTER_INCLUDED_FLAG #define COMPUTER_INCLUDED_FLAG #include "Message.h" class Network; // Network includes pointers to computers so it can't be included class Computer{ protected: char *name; const Network *network; // pointer to the network through which the servers send the messages Computer(Network* _network, char* _name); public: virtual void printDetails() const=0; friend ostream& operator<<(ostream &os, const Computer *c); // this functions uses printDetails() (automorphizm) virtual void receiveMessage(Message*) const=0; virtual ~Computer(); }; #endif

// Computer.cpp
// implementation of Computer class #include "Computer.h" #include "Network.h" #include "String.h" #include <iostream> Computer::Computer(Network* _network, char *_name):network(_network){ int len=strlen(_name)+1; name=new char[len]; strncpy(name,_name,len); } // ctor, (called from the sons) assigns the name and the network pointer for the computer Computer::~Computer(){ delete[] name; };

// Server.h
// header of Server class #ifndef SERVER_INCLUDED_FLAG #define SERVER_INCLUDED_FLAG #include "Computer.h" class Server: public Computer{ public: Server(Network* network,char* _name,int _capacity) private: int capacity virtual void receiveMessage(Message *_message) const virtual void printDetails() const static int nerotChanuka(int n) }; #endif

; ; ; ; ;

// Server.cpp
// implementation of Server class #include "Server.h" #include "Computer.h" #include "MsgReqCalc.h" #include "MsgResult.h" #include "Network.h" #include <iostream> using namespace std; Server::Server(Network* network,char* _name,int _capacity):Computer(network,_name),capacity(_capacity){ } // ctor, assigns the capacity void Server::printDetails() const{ cout<<"Server, "<<name<<", "<<capacity; } // printDetails(), (virtual) prints details void Server::receiveMessage(Message *_message) const{ MsgReqCalc *m=dynamic_cast<MsgReqCalc*>(_message); if(m!=NULL){ int sum; if((sum=nerotChanuka(m->getParam()))>capacity) cout<<"overflow"<<endl; else{ cout<<"calculated "<<sum<<endl; network->sendMessage(new MsgResult(name,sum)); } return; } cout<<"nothing to do"<<endl; } /* receiveMessage(Message*), if it's result message then it prints "noting to do", else (requse message) it checks if sum is bigger then capacity if it's not it prints "overflow", else it sends the result message to evertybody */ int Server::nerotChanuka(int n){ return (int)((double)(n*(n+1))*.5); } // nerotChanuka(n), (static) returns 1+2+...+n

// Client.h
// header of Client class #ifndef ClIENT_INCLUDED_FLAG #define ClIENT_INCLUDED_FLAG #include "Computer.h" class Client: public Computer{ public: Client(Network* network,char *_name) virtual void printDetails() const virtual void receiveMessage(Message *_message) const }; #endif

; ; ;

// Client.cpp
// implementation of Client class #include "Client.h" #include "MsgResult.h" #include <iostream> using namespace std; Client::Client(Network* network,char *_name):Computer(network,_name){ } // Client(char *_name), (ctor) assigns the name of the computer void Client::printDetails() const{ cout<<"Client, "<<name; } // printDetails(), (virtual) prints details void Client::receiveMessage(Message *_message) const{ MsgResult *m=dynamic_cast<MsgResult*>(_message); if(m!=NULL){ cout<<"got "<<m->getResult()<<" from "<<m->getSource()<<endl; return; } cout<<"nothing to do"<<endl; } // receiveMessage (virtual), if it's requset message it prints "noting to do", else (result message) it prints the source and the result

Object-Oriented Programming (83-131), 5771

Home Assignment 4
In this assignment you will exercise inheritance and polymorphism. You are going to implement a simulation of computers that are connected to a broadcast network (everyone hears anything). The computers might be of several types, and therefore respond to different types of messages differently. The operation of the network: There are 2 types of Computers: Server and Client. There are 2 types of Messages: MsgReqCalc and MsgResult. The Server handles messages of type MsgReqCalc (request calculation), and sends the result to the clients as MsgResult. The Client handles messages of type MsgResult, and prints the result. When a computer receives a message it cant handle, it prints nothing to do. The Network holds a list of Computers. The network can only send a message to all the computers. See example on the last page. The classes you will need: 1. Class Computer Holds the computer name and a pointer to the network. receiveMessage method (pure virtual) 2. Class Server Has a capacity. Upon receiving message of type MsgReqCalc (use dynamic_cast to test type and down-cast the message): o o o Perform the calculation: sum = (1 + 2 + ... + param). If sum > capacity, print overflow.

Else, print sum, and send a MsgResult message with the result (using sendMessage on the network). 3. Class Client Upon receiving message of type MsgResult (use dynamic_cast): o Print the source and the result. 4. Class Message 5. Class MsgReqCalc Data: param (int). 6. Class MsgResult Data: source (char[20]), result (int). 7. Class Network Holds Computers (maximum 20). sendMessage method: Sending a message is performed by calling a receiveMessage method of the computers. Use polymorphism so the appropriate method is activated. 8. Class Menu Menu options: 1. add computer: second character is the computer type. 2. send message MsgReqCalc. 3. print. 4. exit.

Notes: You can assume that the user will enter valid data. Use operator<< to print the computers and the messages' details (including their types). All data-members must be private. All strings are of maximum 80 characters. Write header comments for each method in the cpp file and also comments with explanations inside the code.

Running example (grayed text is the user's input):


1 C Client1 1 C Client2 1 S Server1 200 1 C Client3 1 S Server2 500 3 Client, Client1 Client, Client2 Server, Server1, 200 Client, Client3 Server, Server2, 500 2 15 * Sending (MsgReqCalc, 15) Client, Client1: nothing to do Client, Client2: nothing to do Server, Server1, 200: calculated 120 * Sending (MsgResult, Server1, 120) Client, Client1: got 120 from Server1 Client, Client2: got 120 from Server1 Server, Server1, 200: nothing to do Client, Client3: got 120 from Server1 Server, Server2, 500: nothing to do * Finish (MsgResult, Server1, 120) Client, Client3: nothing to do Server, Server2, 500: calculated 120 * Sending (MsgResult, Server2, 120) Client, Client1: got 120 from Server2 Client, Client2: got 120 from Server2 Server, Server1, 200: nothing to do Client, Client3: got 120 from Server2 Server, Server2, 500: nothing to do * Finish (MsgResult, Server2, 120) * Finish (MsgReqCalc, 15) 2 25 * Sending (MsgReqCalc, 25) Client, Client1: nothing to do Client, Client2: nothing to do Server, Server1, 200: overflow Client, Client3: nothing to do Server, Server2, 500: 325 * Sending (MsgResult, Server2, 325) Client, Client1: got 325 from Server2 Client, Client2: got 325 from Server2 Server, Server1, 200: nothing to do Client, Client3: got 325 from Server2 Server, Server2, 500: nothing to do * Finish (MsgResult, Server2, 325) * Finish (MsgReqCalc, 25) 4 // Add client (name: Client1) // Add client // Add server (name: Server1, capacity: 200) // Add client // Add server // Print

All the computer details are printed using operator<< on the computer (with overriding)
// Send MsgReqCalc (param: 15)

The network sends a result right after the server calculated it (recursion). The data in () is printed using operator<< on the message.

After the result was sent to all the computers, the network continues to send the former request.

// Send MsgReqCalc

// Exit

Вам также может понравиться