이번에는 학생 이동 기능에 관해 시퀀스 다이어그램을 작성하고 난 후에 구체적인 코드를 구현합시다.
시나리오를 보면 먼저 이동할 장소를 선택하고 이동할 학생을 선택합니다. 그리고 해당 장소로 학생을 이동합니다.
만약 이동할 장소가 학교일 때는 처음 온 학생인지 확인하여 학번을 부여합니다. 처음 온 학생이라면 학번이 0일 것입니다. 이럴 때는 학번을 부여합니다.
EhNara의 멤버 MoveStudent를 구현합시다.
void EhNara::MoveStudent() //학생 이동 { 먼저 이동할 장소를 선택합니다. Place *place = SelectPlace();//이동할 장소 선택 잘못 선택하였을 때 메시지를 출력하고 메서드를 끝냅니다. if(place==0)//잘못 선택하였을 때 { cout<<"잘못 선택하였습니다."<<endl; return; } 이동할 학생을 선택합니다. Student *stu = SelectStudent();//이동할 학생 선택 잘못 선택하였을 때 메시지를 출력하고 메서드를 끝냅니다. if(stu == 0) { cout<<"잘못 선택하였습니다."<<endl; return; } 선택한 학생을 EhNara에서 제거하고 선택한 장소로 이동합니다. EraseStudent(stu);//학생 제거 place->InStudent(stu);//선택한 장소로 학생 이동 }
EhNara 클래스에 이동할 학생을 선택하는 SelectStudent 메서드와 컬렉션에서 학생 제거하는 EraseStudent 메서드를 추가합니다.
class EhNara:public IComeBack { ...중략... private: ...중략... Student *SelectStudent();//이동할 학생 선택 void EraseStudent(Student *stu);//학생 제거 };
EhNara의 멤버 SelectStudent를 구현합시다. 참고로 현재 실습에서 시퀀스 다이어그램에서는 서로 다른 개체 사이에서의 상호 작용에 관한 것만 표시하고 있습니다.
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]; } } 없을 때는 0을 반환합니다. return 0; }
EhNara의 멤버 EraseStudent 메서드를 구현합시다.
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; } } }
이제 Place 클래스에 유닛 이동 메서드인 InStudent를 선언하세요. 학교에서는 학번을 부여하는 역할을 추가로 해야 하므로 가상 메서드로 정의하세요. 그리고 유닛을 보관할 컬렉션을 멤버 필드로 선언하세요.
class Place { ...중략... SeqArray<Man *> base; public: ...중략... virtual void InStudent(Man *man);//유닛 이동 ...중략... };
Place 클래스의 멤버 InStudent 메서드에서는 컬렉션에 유닛을 순차 보관하세요.
void Place::InStudent(Man *man)//유닛 이동 { base.PushBack(man); }
School 클래스에서 InStudent 메서드를 재정의해야겠죠. 그리고 학번을 부여하기 위해 가장 최근에 부여한 학번을 기억하는 멤버 필드를 선언하세요.
class School : public Place { int last_snum;//가장 최근에 부여한 학생 번호 public: ...중략... virtual void InStudent(Man *man);//유닛 이동 ...중략... };
School 클래스 생성자에서 가장 최근에 부여한 학번을 0으로 설정하세요.
School::School(IComeBack &ic):Place(ic) { last_snum = 0; }
School 클래스의 InStudent 메서드를 구현합시다.
void School::InStudent(Man *man)//유닛 이동 { 기반 형식인 Place의 InStduent 메서드를 호출합니다. 이 부분은 컬렉션에 보관하는 역할을 하는 것이죠. Place::InStudent(man);//기반 형식 Place의 InStudent를 호출(컬렉션에 보관) 처음 온 학생인지 확인하기 위해 학번을 확인합니다. 그리고 처음 온 학생이면 학번을 부여하세요. if(man->GetSNum()==0)//처음 온 학생이면 { last_num++; man->SetSNum(last_snum);//학번 부여 } }
Man 클래스에 학번을 멤버 필드로 추가하세요. 그리고 학번 접근자와 설장자를 추가하세요.
class Man { ...중략... int snum;//학번 public: ...중략... int GetSNum()const;//학번 접근자 void SetSNum(int snum); //학번 설정자 };
Man 클래스 생성자에서 학번을 0으로 설정하세요.
Man::Man(string name):pn(last_pn) { snum = 0; }
Man 클래스의 학번 접근자와 설정자를 구현하세요.
int Man::GetSNum()const//학번 접근자 { return snum; } void Man::SetSNum(int snum) //학번 설정자 { this->snum = snum; }
이제 컴파일 및 빌드하고 테스트 해 보세요.