[디딤돌 C++] 75. 최종 실습 – 초기화 및 해제화

유즈케이스 별로 수행 흐름을 시퀀스로 정의하고 이를 코드로 구현하는 작업을 할 차례입니다. 여기에서는 유즈케이스에는 표현하지 않았지만 EhNara의 초기화 부분과 해제화 부분을 시퀀스 다이어그램으로 작성하고 코드로 옮기는 부분을 먼저 하기로 할게요.

먼저 초기화의 시퀀스 다이어그램을 작성합시다. 시나리오를 보면 EhNara를 생성한 후에 초기화에서는 학생 공장과 학교, 주거지, 다운타운을 생성합니다. 초기화에서 수행할 일은 이것으로 충분합니다.

그런데 학교나 주거지, 다운타운은 학생을 EhNara로 복귀하기 위해 IComeBack 개체가 필요합니다. 따라서 장소의 생성자에는 입력 인자로 IComeBack 개체를 전달해 주어야겠죠.

시퀀스 다이어그램

이제 이 부분을 구현해 봅시다.

EhNara에서는 장소들과 학생 공장을 멤버 필드로 기억하고 있어야 합니다. 이미 앞에서 장소를 기억하는 배열은 멤버 필드로 추가한 상태이므로 학생 공장을 멤버 필드로 추가하세요.

class EhNara:public IComeBack
{
    ....중략...
    Place *places[PI_MAX];
    StuFactory *sf;
    ...중략...
};

이제 초기화 메서드를 구현합시다.

void EhNara::Initialize()
{
학생 공장을 생성하세요.
    sf = new StuFactory();//학생 공장 생성

학교, 다운타운, 주거지 개체를 생성하는 코드는 이미 작성하였습니다. 그런데 입력 인자로 IComeBack & 형식을 전달하기로 시퀀스에 정의하였죠. EhNara는 IComeBack를 기반으로 파생한 개체이므로 *this를 인자로 전달하세요. 이를 통해 각 장소에서 학생을 EhNara에 복귀할 때 전달한 참조 개체를 사용할 수 있습니다.
    //장소 개체 생성
    places[PI_SCHOOL] = new School(*this);
    places[PI_DOWNTOWN] = new Downtown(*this);
    places[PI_VILLAGE] = new Village(*this);
}

이와 같이 수정하였다면 Place 생성자와 School, Downtown, Village의 생성자를 수정하세요. 특히 Place 클래스에서는 학생을 복귀할 때 사용하기 위해 멤버 필드도 추가하세요.

먼저 Place 헤더 파일에는 다음처럼 IComeBack & 형식의 멤버 필드를 추가하시고 생성자의 입력 매개 변수를 수정하세요.

class Place
{
    IComeBack ⁣
public:
    Place(IComeBack &ic);
    ...중략...
};

Place.cpp 에 생성자 부분도 입력 매개 변수를 수정하고 참조 형식 멤버 필드를 초기화하세요.

Place::Place(IComeBack &ic):ic(ic)
{
}

학교, 주거지, 다운타운의 헤더 파일에도 생성자의 입력 매개 변수를 수정하세요.

class School :
    public Place
{
public:
    School(IComeBack &ic);
    ...중략...
};
class Village :
    public Place
{
public:
    Village(IComeBack &ic);
    ...중략...
};
class Downtown:
        public Place
{
public:
    Downtown(IComeBack &ic);
    ...중략...
};

그리고 각 장소의 소스 파일에서도 생성자의 입력 매개 변수를 수정하고 기반 형식 Place를 생성을 초기화하세요.

School::School(IComeBack &ic):Place(ic)
{
}
Village::Village(IComeBack &ic):Place(ic)
{
}
Downtown::Downtown(IComeBack &ic):Place(ic)
{
}

이제 해제화 부분의 시퀀스 다이어그램을 작성합시다. EhNara에 있는 모든 장소를 소멸하고 학생 공장도 소멸합니다. 특히 학생 공장에서는 자신이 생성한 모든 학생 개체를 소멸하세요.

시퀀스 다이어그램

이제 해제화 부분을 구현합시다.

void EhNara::Exit() //해제화
{
이미 모든 장소 개체를 소멸하는 코드는 앞에서 작성했었죠.
    for(int i = 0; i<PI_MAX; i++)//모든 장소 개체 소멸
    {
        delete places[i];
    }
학생 공장 개체를 소멸하는 부분만 추가하세요.
    delete sf;//학생 공장 개체 소멸
}

그리고 학생 공장의 소멸자에서 생산한 모든 학생을 소멸하는 부분을 구현해야겠죠. 그런데 아직 학생 공장은 학생을 보관하는 컬렉션을 추가하지 않았습니다. 먼저 StuFactory 클래스에 컬렉션 멤버 필드를 추가하세요. 여기에서는 SeqArray를 사용합시다.

class StuFactory
{
    SeqArray<Student *> base;
    ...중략...
};

소멸자에서는 컬렉션에 보관한 학생 개체수를 얻어온 후에 순차적으로 모든 학생 개체를 소멸하세요.

StuFactory::~StuFactory(void)
{
    //보관 개수를 얻어온다.
    size_t size = base.GetSize();
    for(size_t i = 0; i<size; ++i)//i를 0~size-1까지 증가
    {
        delete base[i];//학생 개체 소멸
    }
}

이번 실습에서 작성한 코드는 모든 작업을 완료한 후에 소개하기로 할게요. 여러분들께서는 각 단계별로 컴파일 및 빌드하고 테스트하면서 진행하세요.