//ehglobal.h #pragma once enum keydata //기능 키에 사용할 상수 열거 { NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,F8, ESC }; class ehglobal { public: static void clrscr(); //콘솔 화면 클리어 static keydata getkey(); //기능 키 입력 static void waitkey(); //아무 키나 누를 때까지 대기 private: ehglobal(void) { } ~ehglobal(void) { } };
//ehglobal.cpp #include "ehglobal.h" #pragma warning(disable:4996) #include <conio.h> #include <windows.h> void ehglobal::clrscr() { system("cls"); } keydata ehglobal::getkey() { int key = getch(); if(key == 27)//key가 27이면 ESC를 누른 것입니다. { return ESC; } if(key == 0) //key가 0이면 기능 키를 누른 것입니다. { key = getch();//다시 한 번 getkey를 호출해야 합니다. switch(key)//key의 값에 따라 기능 키를 정의한 열거형의 상수를 반환합니다. { case 59: return F1; case 60: return F2; case 61: return F3; case 62: return F4; case 63: return F5; case 64: return F6; case 65: return F7; case 66: return F8; } } return NO_DEFINED; } void ehglobal::waitkey() { getkey(); }
//SeqArray.h #pragma once template <typename data> class SeqArray { data *base; //저장소 size_t capacity; //저장소 크기 size_t size; //보관 개수 public: SeqArray() { base = 0; capacity = 0; size = 0; } ~SeqArray(void) { if(base)//저장소가 있을 때 { delete[] base;//저장소 해제 } } void PushBack(data value)//순차 보관 { if(IsFull())//꽉차면 { if(capacity)//저장소의 개수가 참일 때 { Reserve(capacity *2);//두 배로 확장 } else//아닐 때(0일 때) { Reserve(1);//1로 확장 } } base[size] = value;//보관 size++;//보관 개수 1 증가 } void RemoveAt(size_t index)//특정 인덱스 요소 삭제 { if(IsAvailIndex(index)==false)//인덱스가 유효하지 않을 때 { return; } size--;//보관 개수 1 감소 for( ;index<size;index++) { base[index] = base[index+1];//한 칸씩 앞으로 이동 } } template <typename find_if> int FindIf(find_if fun)//특정 알고리즘이 처음으로 참인 위치 찾기 { for(size_t i = 0; i<size; ++i) { if(fun(base[i]))//알고리즘에 적용하였을 때 참이면 { return i; //인덱스 반환 } } return -1;//-1 반환 } data &operator[](size_t index)//인덱서 { if(IsAvailIndex(index)==false)//유효하지 않은 인덱스일 때 { throw "유효하지 않은 인덱스를 사용하였습니다.";//예외 던짐 } return base[index];//인덱스의 원소 반환 } bool IsAvailIndex(size_t index)const//유효한 인덱스인지 판별 { return (index>=0)&&(index<size); } size_t GetSize()const { return size; } private: bool IsFull()const//꽉 찼는지 판별 { return size == capacity; } void Reserve(int ncapacity)//저장소 확장 { data *tbuf = base;//저장소 위치를 tbuf로 설정 base = new data[ncapacity];//저장소 동적 할당 capacity = ncapacity;//저장소 크기 설정 if(tbuf)//이전 저장소가 참이면 { for(size_t i=0; i<size;++i) { base[i] = tbuf[i];//이전 저장소에 보관한 값을 새로운 저장소로 이동 } delete[] tbuf;//이전 저장소 메모리 해제 } } };
//IPlay.h #pragma once #ifndef interface #define interface struct #endif interface IPlay { virtual void Drink()=0; virtual void Sing()=0; };
//IRelax.h #pragma once #ifndef interface #define interface struct #endif interface IRelax { virtual void Sleep()=0; virtual void Relax()=0; };
//IStudy.h #pragma once #ifndef interface #define interface struct #endif interface IStudy { virtual void ListenLecture()=0; virtual void Study()=0; };
//Man.h #pragma once #include <iostream> #include <string> using namespace std; class Man { static int last_pn; const int pn; string name; int snum;//학번 public: Man(string name); int GetPN()const; string GetName()const; int GetSNum()const;//학번 접근자 void SetSNum(int snum); //학번 설정자 virtual void View()const=0;//정보보기 };
//Man.cpp #include "Man.h" int Man::last_pn; Man::Man(string name):pn(++last_pn) { this->name = name; snum = 0; } int Man::GetPN()const { return pn; } string Man::GetName()const { return name; } int Man::GetSNum()const//학번 접근자 { return snum; } void Man::SetSNum(int snum) //학번 설정자 { this->snum = snum; }
//IComeBack.h #pragma once #ifndef interface #define interface struct #endif #include "Man.h" interface IComeBack { virtual void ComeBack(Man *man)=0; };
//StuConst.h #pragma once class StuConst { public: static const int def_iq; static const int max_iq; static const int min_iq; static const int def_hp; static const int max_hp; static const int min_hp; static const int def_stress; static const int max_stress; static const int min_stress; static const int def_scnt; static const int max_scnt; static const int min_scnt; private://개체를 생성할 수 없게 함 StuConst(void); };
//StuConst.cpp #include "StuConst.h" const int StuConst::def_iq = 100; const int StuConst::max_iq=200; const int StuConst::min_iq=0; const int StuConst::def_hp=100; const int StuConst::max_hp=200; const int StuConst::min_hp=0; const int StuConst::def_stress=0; const int StuConst::max_stress=100; const int StuConst::min_stress=0; const int StuConst::def_scnt=0; const int StuConst::max_scnt=5; const int StuConst::min_scnt=0; StuConst::StuConst(void) { }
//Student.h #pragma once #include "Man.h" #include "IPlay.h" #include "IRelax.h" #include "IStudy.h" #include "StuConst.h" using namespace std; class Student:public Man, public IStudy, public IRelax, public IPlay { int iq; int hp; int stress; int scnt; public: friend class StuFactory; virtual void Study(); virtual void ListenLecture(); virtual void Sleep(); virtual void Relax(); virtual void Drink(); virtual void Sing(); virtual void View()const; int GetIQ()const; int GetHP()const; int GetStress()const; int GetSCnt()const; protected: Student(string name); void SetIQ(int iq); void SetHP(int hp); void SetStress(int stress); void SetSCnt(int scnt); };
//Student.cpp #include "Student.h" #define SC StuConst //간략하게 사용할 수 있게 매크로 정의 Student::Student(string name):Man(name) { SetIQ(SC::def_iq); SetHP(SC::def_hp); SetStress(SC::def_stress); SetSCnt(SC::def_scnt); } void Student::View()const { cout<<"주민 번호:"<<GetPN()<<" 이름:"<<GetName()<<endl; cout<<" IQ:"<<iq<<" HP:"<<hp<<" Stress:"<<stress<<endl; cout<<" 연속으로 공부한 횟수:"<<scnt<<endl; } int Student::GetIQ()const { return iq; } int Student::GetHP()const { return hp; } int Student::GetStress()const { return stress; } int Student::GetSCnt()const { return scnt; } void Student::SetIQ(int iq) { if(iq>SC::max_iq) { iq = SC::max_iq; } if(iq<SC::min_iq) { iq = SC::min_iq; } this->iq = iq; } void Student::SetHP(int hp) { if(hp>SC::max_hp) { hp = SC::max_hp; } if(hp<SC::min_hp) { hp = SC::min_hp; } this->hp = hp; } void Student::SetStress(int stress) { if(stress>SC::max_stress) { stress = SC::max_stress; } if(stress<SC::min_stress) { stress = SC::min_stress; } this->stress = stress; } void Student::SetSCnt(int scnt) { if(scnt>SC::max_scnt) { scnt = SC::max_scnt; } if(scnt<SC::min_scnt) { scnt = SC::min_scnt; } this->scnt = scnt; } void Student::ListenLecture() { cout<<GetName()<<" 강의받다."<<endl; } void Student::Study() { cout<<GetName()<<" 공부하다."<<endl; } void Student::Sleep() { cout<<GetName()<<" 잠을 자다."<<endl; } void Student::Relax() { cout<<GetName()<<" 휴식하다."<<endl; } void Student::Drink() { cout<<GetName()<<" 음료를 마시다."<<endl; } void Student::Sing() { cout<<GetName()<<" 노래하다."<<endl; }
//MStudent.h #pragma once #include "Student.h" class MStudent : public Student { int stick; public: friend class StuFactory; virtual void Study(); virtual void ListenLecture(); virtual void Sleep(); virtual void Relax(); virtual void Drink(); virtual void Sing(); virtual void View()const; void Travel(); private: MStudent(string name); };
//MStudent.cpp #include "MStudent.h" MStudent::MStudent(string name):Student(name) { stick=0;//지팡이는 생성 시 0 } void MStudent::Study() { Student::Study(); Student::ListenLecture(); SetHP(GetHP()-3);//체력 3소모 SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가 SetStress(GetStress()+3);//스트레스: 3증가 SetSCnt(GetSCnt()+1); } void MStudent::ListenLecture() { SetHP(GetHP()-2); //체력 2소모 SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가 SetStress(GetStress()+5);// 스트레스: 5증가 SetSCnt(0); } void MStudent::Sleep() { Student::Sleep(); SetHP(GetHP()+10); //체력 10회복 SetStress(GetStress()-5); //스트레스: 5감소 SetSCnt(0); } void MStudent::Relax() { Student::Relax(); SetHP(GetHP()+3); //체력 3회복 SetStress(GetStress()-25); //스트레스: 25감소 SetSCnt(0); } void MStudent::Drink() { Student::Drink(); SetHP(GetHP()+5+stick); //체력 5+지팡이 회복 SetIQ(GetIQ()-(10-stick));//지력: 10-지팡이 감소 SetStress(GetStress()-2);//스트레스: 2감소 SetSCnt(0); } void MStudent::Sing() { Student::Sing(); SetHP(GetHP()-(10-stick)); //체력 10-지팡이 소모 SetIQ(GetIQ()-5);//지력: 5감소 SetStress(GetStress()-5);//스트레스: 5감소 SetSCnt(0); } void MStudent::View()const { cout<<"마법 학생"; Student::View(); cout<<" 지팡이:"<<stick<<endl; } void MStudent::Travel() { cout<<GetName()<<" 여행하다."<<endl; stick++;//지팡이 1증가 }
//PStudent.h #pragma once #include "Student.h" class PStudent : public Student { int air; public: friend class StuFactory; virtual void Study(); virtual void ListenLecture(); virtual void Sleep(); virtual void Relax(); virtual void Drink(); virtual void Sing(); virtual void View()const; void Dance(); private: PStudent(string name); };
//PStudent..cpp #include "PStudent.h" PStudent::PStudent(string name):Student(name) { air=0;//air는 생성 시 0 } void PStudent::Study() { Student::Study(); SetHP(GetHP()-2);//체력 2소모 SetIQ(GetIQ()+GetSCnt()/2);//지력: scnt/2 증가 air-=3; SetStress(GetStress()-air*3);//스트레스: air*3감소 SetSCnt(GetSCnt()+1); } void PStudent::ListenLecture() { Student::ListenLecture(); SetHP(GetHP()-1); //체력 1소모 SetIQ(GetIQ()+GetSCnt()/2);//지력: scnt/2 증가 air-=5; SetStress(GetStress()-air*3);// 스트레스: air*3 감소 SetSCnt(0); } void PStudent::Sleep() { Student::Sleep(); SetHP(GetHP()+10); //체력 10회복 SetStress(GetStress()-5); //스트레스: 5감소 SetSCnt(0); } void PStudent::Relax() { Student::Relax(); SetHP(GetHP()+8); //체력 8회복 SetStress(GetStress()-25); //스트레스: 25감소 SetSCnt(0); } void PStudent::Drink() { Student::Drink(); SetHP(GetHP()+5); //체력 5 회복 SetIQ(GetIQ()-3);//지력: 3 감소 SetStress(GetStress()-2);//스트레스: 2감소 SetSCnt(0); } void PStudent::Sing() { Student::Sing(); SetHP(GetHP()-5); //체력 5 소모 SetIQ(GetIQ()+2);//지력: 5증가 SetStress(GetStress()-5);//스트레스: 5감소 SetSCnt(0); } void PStudent::View()const { cout<<"운동 학생"; Student::View(); cout<<" air:"<<air<<endl; } void PStudent::Dance() { cout<<GetName()<<" 춤을 추다."<<endl; SetHP(GetHP()-5); //체력 5 소모 SetIQ(GetIQ()+3);//지력: 3증가 air++;//air 1증가 }
//SStudent.h #pragma once #include "Student.h" class SStudent : public Student { int dummy; int total_scnt; public: friend class StuFactory; virtual void Study(); virtual void ListenLecture(); virtual void Sleep(); virtual void Relax(); virtual void Drink(); virtual void Sing(); virtual void View()const; void Reading(); private: SStudent(string name); };
//SStudent..cpp #include "SStudent.h" SStudent::SStudent(string name):Student(name) { dummy = 0;//더미 뇌는 생성 시 0 total_scnt = 0; } void SStudent::Study() { Student::Study(); SetHP(GetHP()-5);//체력 5소모 SetIQ(GetIQ()+GetSCnt()+dummy);//지력: scnt+더미 뇌 증가 SetStress(GetStress()-2);//스트레스: 2감소 SetSCnt(GetSCnt()+1); total_scnt++; if(total_scnt%5 == 0)//더미 뇌는 공부한 회수가 5의 배수가 될 때마다 1씩 증가 { dummy++; } } void SStudent::ListenLecture() { Student::ListenLecture(); SetHP(GetHP()-3); //체력 3소모 SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가 SetStress(GetStress()+GetSCnt());// 스트레스: scnt증가 SetSCnt(0); } void SStudent::Sleep() { Student::Sleep(); SetHP(GetHP()+10); //체력 10회복 SetStress(GetStress()-5); //스트레스: 5감소 SetSCnt(0); } void SStudent::Relax() { Student::Relax(); SetHP(GetHP()+3); //체력 3회복 SetStress(GetStress()-25); //스트레스: 25감소 SetSCnt(0); } void SStudent::Drink() { Student::Drink(); SetHP(GetHP()+5); //체력 5회복 SetIQ(GetIQ()-10);//지력: 10감소 SetStress(GetStress()+2);//스트레스: 2증가 SetSCnt(0); } void SStudent::Sing() { Student::Sing(); SetHP(GetHP()-10); //체력 10 소모 SetIQ(GetIQ()-(5-GetSCnt()));//지력: 5-scnt감소 SetStress(GetStress()+(5-GetSCnt()));//스트레스: 5-scnt증가 SetSCnt(0); } void SStudent::View()const { cout<<"학사 학생"; Student::View(); cout<<" 더미 뇌:"<<dummy<<"연속으로 공부한 횟수:"<<total_scnt<<endl; } void SStudent::Reading() { cout<<GetName()<<" 독서하다."<<endl; dummy++;//더미 뇌 1증가 SetStress(GetStress()-5);//스트레스: 5감소 }
//StuFactory.h #pragma once #include "SeqArray.h" #include "Student.h" class StuFactory { SeqArray<Student *> base; public: StuFactory(void); ~StuFactory(void); Student *MakeStudent(int stype,string name);//학생 생성 };
//StuFactory.cpp #include "StuFactory.h" #include "SStudent.h" #include "MStudent.h" #include "PStudent.h" StuFactory::StuFactory(void) { } StuFactory::~StuFactory(void) { //보관 개수를 얻어온다. size_t size = base.GetSize(); for(size_t i = 0; i<size; ++i)//i를 0~size-1까지 증가 { delete base[i];//학생 개체 소멸 } } Student *StuFactory::MakeStudent(int stype,string name)//학생 생성 { Student *stu = 0; //stype에 따라 적절한 학생 개체 생성 switch(stype) { case 1: stu = new SStudent(name); break; case 2: stu = new MStudent(name); break; case 3: stu = new PStudent(name); break; default: throw "학생 타입 범위를 벗어났습니다."; } base.PushBack(stu);//생성한 학생 개체를 컬렉션에 보관 return stu;//생성한 학생 개체 반환 }
//Place.h #pragma once #include "IComeBack.h" #include "Man.h" #include "SeqArray.h" #include "ehglobal.h" class Place { IComeBack ⁣ SeqArray<Man *> base; public: Place(IComeBack &ic); ~Place(void); void Run(); virtual void InStudent(Man *man);//유닛 이동 virtual void View();//장소 정보 출력 protected: int SelectMenu(); virtual void ViewMenu()const; void ComeBackStu();//학생 복귀 virtual void DoItByKey(int key)=0;//키에 따라 기능 수행 Man *SelectMan();//학생 선택 size_t GetCount()const;//학생 수 Man *GetAt(size_t index);//index 위치 학생 반환 private: void EraseMan(Man *man);//학생 제거 };
//Place.cpp #include "Place.h" Place::Place(IComeBack &ic):ic(ic) { } Place::~Place(void) { } void Place::Run() { int key = 0; while((key = SelectMenu())!=ESC) { if(key == F1) { ComeBackStu();//학생 복귀 } else { DoItByKey(key);//키에 따라 기능 수행 } cout<<"아무 키나 누르세요."<<endl; ehglobal::getkey(); } } int Place::SelectMenu() { ehglobal::clrscr(); ViewMenu(); return ehglobal::getkey(); } void Place::ViewMenu()const { cout<<"ESC:초점 종료"<<endl; cout<<"F1: 이에이치 나라로 학생 복귀"<<endl; } void Place::ComeBackStu()//유닛 복귀 { Man *man = SelectMan();//이동할 유닛 선택 if(man == 0) { cout<<"잘못 선택하였습니다."<<endl; return; } EraseMan(man);//유닛 제거 ic.ComeBack(man);//학생 복귀 } Man *Place::SelectMan()//유닛 선택 { cout<<"선택할 학생의 주민번호:"; int pn=0; cin>>pn; size_t size = base.GetSize();//보관한 학생 수 구하기 for(size_t i=0;i<size;++i) { if(base[i]->GetPN() == pn)//학생 주민번호와 입력한 주민번호가 같을 때 { return base[i]; } } return 0; } void Place::EraseMan(Man *man)//유닛 제거 { size_t size = base.GetSize();//보관한 학생 수 구하기 for(size_t i=0;i<size;++i) { if(base[i]==man)//보관한 학생과 입력 인자로 받은 학생이 같을 때 { base.RemoveAt(i);//해당 인덱스에 보관한 개체 지우기 return; } } } void Place::InStudent(Man *man)//유닛 이동 { base.PushBack(man); } void Place::View()//장소 정보 출력 { size_t size = base.GetSize();//보관 개수를 얻어온다. for(size_t i = 0; i<size; ++i)//i를 0~size-1까지 증가 { base[i]->View();//학생 정보 출력 } } size_t Place::GetCount()const//학생 수 { return base.GetSize(); } Man *Place::GetAt(size_t index)//index 위치 학생 반환 { return base[index]; }
//Downtown.h #pragma once #include "Place.h" #include "PStudent.h" #include "IPlay.h" class Downtown: public Place { public: Downtown(IComeBack &ic); ~Downtown(void); virtual void View();//장소 정보 출력 private: virtual void ViewMenu()const; //메뉴 출력 virtual void DoItByKey(int key);//키에 따라 기능 수행 void Party();//파티 void GoToSing();//노래방으로 가기 };
//Downtown.cpp #include "Downtown.h" Downtown::Downtown(IComeBack &ic):Place(ic) { } Downtown::~Downtown(void) { } void Downtown::ViewMenu()const //메뉴 출력 { Place::ViewMenu(); cout<<"F2: 파티"<<endl; cout<<"F3: 노래방으로 가기"<<endl; } void Downtown::DoItByKey(int key)//키에 따라 기능 수행 { switch(key) { case F2: Party(); break; //파티 case F3: GoToSing(); break; //노래방으로 가기 default: cout<<"잘못 선택하였습니다."<<endl; } } void Downtown::Party()//파티 { cout<<"파티"<<endl; size_t max = GetCount();//학생 수 구하기 for(size_t index = 0; index<max; ++index) { IPlay *iplay = dynamic_cast<IPlay *>(GetAt(index)); if(iplay) { iplay->Drink(); } else { throw "장소에 있는 개체가 IPlay 형식으로 하향 캐스팅을 할 수 없습니다."; } } } void Downtown::GoToSing()//노래방으로 가기 { cout<<"노래방으로 가기"<<endl; Man *man = SelectMan(); if(man==0) { cout<<"잘못 선택하였습니다."<<endl; return; } IPlay *iplay = dynamic_cast<IPlay *>(man); if(iplay) { iplay->Sing(); PStudent *pstu = dynamic_cast<PStudent *>(iplay); if(pstu) { pstu->Dance(); } } else { throw "IPlay 형식으로 하향 캐스팅을 하지 못하였습니다."; } } void Downtown::View()//장소 정보 출력 { cout<<"다운타운 "<<endl; Place::View(); }
//School.h #pragma once #include "Place.h" #include "IStudy.h" #include "SStudent.h" class School : public Place { int last_snum;//가장 최근에 부여한 학생 번호 public: School(IComeBack &ic); ~School(void); virtual void InStudent(Man *man);//유닛 이동 virtual void View();//장소 정보 출력 private: virtual void ViewMenu()const; //메뉴 출력 virtual void DoItByKey(int key);//키에 따라 기능 수행 void StartLecture();//강의 시작 void GoToLibrary();//도서관으로 가기 };
//School.cpp #include "School.h" School::School(IComeBack &ic):Place(ic) { last_snum = 0; } School::~School(void) { } void School::ViewMenu()const //메뉴 출력 { Place::ViewMenu(); cout<<"F2: 강의 시작"<<endl; cout<<"F3: 도서관으로 가기"<<endl; } void School::DoItByKey(int key)//키에 따라 기능 수행 { switch(key) { case F2: StartLecture(); break; //강의 시작 case F3: GoToLibrary(); break; //도서관으로 가기 default: cout<<"잘못 선택하였습니다."<<endl; } } void School::StartLecture()//강의 시작 { cout<<"강의 시작"<<endl; size_t max = GetCount();//학생 수 구하기 for(size_t index = 0; index<max; ++index) { IStudy *istudy = dynamic_cast<IStudy *>(GetAt(index)); if(istudy) { istudy->ListenLecture(); } else { throw "장소에 있는 개체가 IStudy 형식으로 하향 캐스팅을 할 수 없습니다."; } } } void School::GoToLibrary()//도서관으로 가기 { cout<<"도서관으로 가기"<<endl; Man *man = SelectMan(); if(man==0) { cout<<"잘못 선택하였습니다."<<endl; return; } IStudy *istudy = dynamic_cast<IStudy *>(man); if(istudy) { istudy->Study(); SStudent *sstu = dynamic_cast<SStudent *>(istudy); if(sstu) { sstu->Reading(); } } else { throw "IStudy 형식으로 하향 캐스팅을 하지 못하였습니다."; } } void School::InStudent(Man *man)//유닛 이동 { Place::InStudent(man);//기반 형식 Place의 InStudent를 호출(컬렉션에 보관) if(man->GetSNum()==0)//처음 온 학생이면 { last_snum++; man->SetSNum(last_snum);//학번 부여 } } void School::View()//장소 정보 출력 { cout<<"학교 "<<endl; Place::View(); }
//Village.h #pragma once #include "Place.h" #include "IRelax.h" #include "MStudent.h" class Village : public Place { public: Village(IComeBack &ic); ~Village(void); virtual void View();//장소 정보 출력 private: virtual void ViewMenu()const; //메뉴 출력 virtual void DoItByKey(int key);//키에 따라 기능 수행 void TurnOff();//소등 void GoToLivingRoom();//거실로 가기 };
//Village.cpp #include "Village.h" Village::Village(IComeBack &ic):Place(ic) { } Village::~Village(void) { } void Village::ViewMenu()const //메뉴 출력 { Place::ViewMenu(); cout<<"F2: 소등"<<endl; cout<<"F3: 거실로 가기"<<endl; } void Village::DoItByKey(int key)//키에 따라 기능 수행 { switch(key) { case F2: TurnOff(); break; //강의 시작 case F3: GoToLivingRoom(); break; //도서관으로 가기 default: cout<<"잘못 선택하였습니다."<<endl; } } void Village::TurnOff()//소등 { cout<<"소등"<<endl; size_t max = GetCount();//학생 수 구하기 for(size_t index = 0; index<max; ++index) { IRelax *irelax = dynamic_cast<IRelax *>(GetAt(index)); if(irelax) { irelax->Sleep(); } else { throw "장소에 있는 개체가 IRelax 형식으로 하향 캐스팅을 할 수 없습니다."; } } } void Village::GoToLivingRoom()//거실로 가기 { cout<<"거실로 가기"<<endl; Man *man = SelectMan(); if(man==0) { cout<<"잘못 선택하였습니다."<<endl; return; } IRelax *irelax = dynamic_cast<IRelax *>(man); if(irelax) { irelax->Relax(); MStudent *mstu = dynamic_cast<MStudent *>(irelax); if(mstu) { mstu->Travel(); } } else { throw "IRelax 형식으로 하향 캐스팅을 하지 못하였습니다."; } } void Village::View()//장소 정보 출력 { cout<<"주거지 "<<endl; Place::View(); }
//EhNara.h #pragma once #include "SeqArray.h" #include "StuFactory.h" #include "IComeBack.h" #include "Place.h" #include "Student.h" class EhNara:public IComeBack { static EhNara app;//단일체 enum PIndex//장소 인덱스 { PI_SCHOOL, PI_DOWNTOWN, PI_VILLAGE, PI_MAX }; Place *places[PI_MAX]; StuFactory *sf; SeqArray<Student *> base; public: static void Start();//응용 시작 - 진입점에서 호출하는 정적 메서드 virtual void ComeBack(Man *man);//학생 복귀 private: EhNara(void); ~EhNara(void); void Initialize(); //초기화 void Run(); //사용자와 상호 작용 void Exit(); //해제화 int SelectMenu(); //메뉴 출력 및 선택 void MakeStudent(); //학생 생성 void MoveFocus(); //초점 이동 void MoveStudent(); //학생 이동 void ViewAll(); //전체 보기 Place *SelectPlace();//장소 선택 Student *SelectStudent();//이동할 학생 선택 void EraseStudent(Student *stu);//학생 제거 void ViewStudents();//전체 학생 정보 보기 void ViewPlaces();//전체 장소 정보 보기 };
//EhNara.cpp #include "EhNara.h" #include "School.h" #include "Downtown.h" #include "Village.h" EhNara EhNara::app;//단일체 void EhNara::Start()//응용 시작 - 진입점에서 호출하는 정적 메서드 { app.Initialize(); app.Run(); app.Exit(); } EhNara::EhNara(void) { } EhNara::~EhNara(void) { } void EhNara::Initialize() { sf = new StuFactory();//학생 공장 생성 //장소 개체 생성 places[PI_SCHOOL] = new School(*this); places[PI_DOWNTOWN] = new Downtown(*this); places[PI_VILLAGE] = new Village(*this); } void EhNara::Run() { int key = 0; while((key = SelectMenu())!=ESC) { switch(key) { case F1: MakeStudent(); break; case F2: MoveFocus(); break; case F3: MoveStudent(); break; case F4: ViewAll(); break; default: cout<<"잘못 선택하였습니다."<<endl; break; } cout<<"아무 키나 누르세요."<<endl; ehglobal::getkey(); } } void EhNara::Exit() //해제화 { for(int i = 0; i<PI_MAX; i++)//모든 장소 개체 해제 { delete places[i]; } delete sf;//학생 공장 개체 소멸 } int EhNara::SelectMenu() //메뉴 출력 및 선택 { ehglobal::clrscr(); cout<<"이에이치 나라 메뉴"<<endl; cout<<"F1: 학생 생성 F2: 초점 이동 F3: 학생 이동 F4: 전체 보기 ESC: 프로그램 종료"<<endl; return ehglobal::getkey(); } void EhNara::MakeStudent() //학생 생성 { cout<<"생성할 학생 유형을 선택하세요. [1]:학사학생 [2]:마법학생 [3]:운동학생"<<endl; int stype; cin>>stype; if((stype<1)||(stype>3))//잘못 선택하였을 때 { cout<<"잘못 선택하였습니다."<<endl; return; } cout<<"학생 이름:"; string name; cin>>name; Student *stu = sf->MakeStudent(stype,name);//학생 생성 요청 base.PushBack(stu);//생성한 학생 보관 } void EhNara::MoveFocus() //초점 이동 { Place *place = SelectPlace();//장소 선택 if(place==0) { cout<<"잘못 선택하였습니다."<<endl; return; } place->Run();//장소의 상호 작용 } void EhNara::MoveStudent() //학생 이동 { Place *place = SelectPlace();//이동할 장소 선택 if(place==0)//잘못 선택하였을 때 { cout<<"잘못 선택하였습니다."<<endl; return; } Student *stu = SelectStudent();//이동할 학생 선택 if(stu == 0) { cout<<"잘못 선택하였습니다."<<endl; return; } EraseStudent(stu);//학생 제거 place->InStudent(stu);//선택한 장소로 학생 이동 } void EhNara::ViewAll() //전체 보기 { ViewStudents();//전체 학생 정보 보기 ViewPlaces();//전체 장소 정보 보기 } void EhNara::ViewStudents()//전체 학생 정보 보기 { size_t size = base.GetSize();//보관 개수를 얻어온다. for(size_t i = 0; i<size; ++i)//i를 0~size-1까지 증가 { base[i]->View();//학생 정보 출력 } } void EhNara::ViewPlaces()//전체 장소 정보 보기 { for(int i = 0; i<PI_MAX; i++) { places[i]->View();//장소 정보 출력 } } Place *EhNara::SelectPlace()//장소 선택 { cout<<"장소를 선택하세요."<<endl; cout<<"1: 학교 2: 다운타운 3: 주거지"<<endl; int pi=0; cin>>pi; if((pi<1)&&(pi>PI_MAX))//유효한 선택이 아닐 때 { return 0; } return places[pi-1]; } Student *EhNara::SelectStudent()//이동할 학생 선택 { cout<<"선택할 학생의 주민번호:"; int pn=0; cin>>pn; size_t size = base.GetSize();//보관한 학생 수 구하기 for(size_t i=0;i<size;++i) { if(base[i]->GetPN() == pn)//학생 주민번호와 입력한 주민번호가 같을 때 { return base[i]; } } return 0; } void EhNara::EraseStudent(Student *stu)//학생 제거 { size_t size = base.GetSize();//보관한 학생 수 구하기 for(size_t i=0;i<size;++i) { if(base[i]==stu)//보관한 학생과 입력 인자로 받은 학생이 같을 때 { base.RemoveAt(i);//해당 인덱스에 보관한 개체 지우기 return; } } } void EhNara::ComeBack(Man *man)//학생 복귀 { Student *stu = dynamic_cast<Student *>(man); if(stu == 0) { throw "Student 형식이 아닙니다."; } base.PushBack(stu);//순차 보관 }
//Program.cpp #include "EhNara.h" int main() { EhNara::Start(); return 0; }
이상으로 디딤돌 C++를 마칠게요. 모두 행복한 엔지니어 생활하시길 바랄게요.