7.5.1 STL map 사용 방법 1

이제 첫 번째 방법인 insert, find, erase, iterator 사용하는 방법으로 구현해 보기로 해요.

먼저 반복자를 타입 재지정하세요.

typedef MDic::iterator MIter;
typedef MDic::const_iterator CMIter;

먼저 회원 추가 기능을 구현합시다.

void App::AddMember() //회원 추가
{

먼저 주요 키인 아이디를 입력받으세요.

    cout<<"추가할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();

같은 키를 갖는 회원 개체가 있는지 탐색하세요.

map이나 list에서는 알고리즘 find 혹은 find_if 메서드를 사용해서 탐색했었죠. map도 알고리즘 find와 find_if를 사용할 수 있어요. 하지만 이는 순차 탐색하는 것이며 빠른 탐색을 원하면 map에 제공하는 멤버 find 메서드를 사용하세요.

    MIter seek = mdic.find(id); //map의 find 메서드에 키(회원 아이디)로 위치 찾기

만약 반환 값이 end와 같지 않다면 탐색이 성공한 것입니다.

    if(seek != mdic.end())//seek가 base.end()와 같지 않으므로 seek위치에 보관되어 있음
    {

탐색이 성공했다는 것은 이미 존재하는 아이디이므로 메시지를 출력하고 기능을 종료하세요.

        cout<<"이미 존재하는 아이디입니다."<<endl;
        return;
    }

회원 이름을 입력받습니다.

    cout<<"회원 이름을 입력하세요."<<endl;
    string name = ehglobal::getstr();

보관할 데이터는 id를 키로 회원 개체를 값으로 하는 pair 입니다.

    //map은 키와 값으로 구성된 pair를 보관
    pair<string, Member *> pd(id,new Member(id,name));

추가할 때 insert 메서드를 사용하세요. vector와 list와 다르게 insert 메서드에 위치 정보를 전달하지 않습니다. 이는 map 내부에서 입력받은 pair의 key 값으로 탐색할 위치를 찾아 보관하기 때문이예요.

    mdic.insert(pd);
}

이제 회원 삭제 기능을 구현합시다.

void App::RemoveMember()//회원 삭제
{

삭제할 아이디를 입력받으세요.

    cout<<"삭제할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();

삭제할 데이터를 찾을 때도 find 메서드를 사용하세요.

    MIter seek = mdic.find(id); //map의 find 메서드에 키로 보관된 요소 찾기

만약 반환한 위치가 end와 같다면 탐색 실패입니다. 메시지를 출력하고 기능을 종료하세요.

    if(seek == mdic.end())//seek가 base.end()와 같다면 검색 조건에 맞는 요소가 없음
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }

map에서는 키와 쌍을 값으로 하는 pair를 보관했습니다. 따라서 반복자의 간접 연산은 pair 형식의 자료입니다. pair 형식은 first 멤버가 key이고 second 멤버가 second입니다. 반복자의 간접 연산으로 접근한 pair의 second 멤버인 회원 개체를 소멸하세요.

    delete (*seek).second; //pair의 second는 값인 회원 개체 소멸

vector와 list처럼 erase 메서드로 반복자 위치에 보관한 자료를 지우세요.

    mdic.erase(seek);
    cout<<"삭제하였습니다."<<endl;
}

검색 기능도 삭제 기능과 비슷합니다.

void App::FindMember()const //회원 검색    
{

검색할 아이드를 입력받아 검색하세요.

    cout<<"검색할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();    
    CMIter seek = mdic.find(id); //map의 find 메서드에 키로 보관된 요소 찾기    

검색 실패일 때 메시지를 출력하고 기능을 종료하세요.

    if(seek == mdic.end())//seek가 base.end()와 같다면 검색 조건에 맞는 요소가 없음
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }

반복자의 간접 연산으로 접근한 pair의 second 멤버인 회원 개체의 정보를 출력하세요.

    Member *member = (*seek).second;
    member->View();    
}

전체 보기는 반복자를 이용합니다.

void App::ListAll()const //전체 보기
{
    CMIter seek = mdic.begin();
    CMIter end = mdic.end();
    Member *member = 0; 

반복자의 간접 연산으로 접근한 pair의 second 멤버인 회원 개체의 정보를 출력하세요.

    //반복자를 사용하여 차례대로 회원의 정보를 출력
    for(  ; seek != end ; ++seek)
    {
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        member->View();
    }
}

소멸자에서는 App 내부에서 생성한 회원 개체를 모두 소멸하세요.

App::~App()
{
소멸자에서는 App 내부에서 생성한 회원 개체를 모두 소멸하세요.
    MIter seek = mdic.begin();
    MIter end = mdic.end();
    Member *member = 0; 

    for(  ; seek != end ; ++seek)
    {
        //반복자의 간접 연산으로 접근한 pair의 second 멤버인 회원 개체를 소멸하세요.
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        delete member;
    }
}

다음은 앞에서 구현한 App.cpp 파일의 내용입니다. 다른 소스 코드는 이전 게시글 을 참고하세요.

//App.cpp
#include "App.h"

typedef MDic::iterator MIter;
typedef MDic::const_iterator CMIter;

void App::Run()
{
    int key=NO_DEFINED;

    while((key = SelectMenu())!=ESC)
    {
        switch(key)
        {
        case F1: AddMember(); break;
        case F2: RemoveMember(); break;
        case F3: FindMember(); break;
        case F4: ListAll(); break;        
        default: cout<<"잘못 선택하셨습니다."<<endl; break;
        }

        cout<<"아무 키나 누르세요."<<endl;
        ehglobal::getkey();
    }
}

int App::SelectMenu()
{
    ehglobal::clrscr();//콘솔 화면을 지우기
    cout<<"회원 관리 프로그램 [ESC]: 종료"<<endl;
    cout<<"F1: 회원 추가 F2: 회원 삭제 F3: 회원 검색 F4: 전체 보기"<<endl;

    return ehglobal::getkey();//사용자가 입력한 기능 키 반환
}

void App::AddMember() //회원 추가
{    
    cout<<"추가할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();    



    MIter seek = mdic.find(id); //map의 find 메서드에 키(회원 아이디)로 위치 찾기

    if(seek != mdic.end())//seek가 base.end()와 같지 않으므로 seek위치에 보관되어 있음
    {
        cout<<"이미 존재하는 아이디입니다."<<endl;   return;
    }
    cout<<"회원 이름을 입력하세요."<<endl;
    string name = ehglobal::getstr();    
    pair<string, Member *> pd(id,new Member(id,name));
    mdic.insert(pd);
}

void App::RemoveMember()//회원 삭제
{
    cout<<"삭제할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();    
    MIter seek = mdic.find(id); //map의 find 메서드에 키로 보관된 요소 찾기    

    if(seek == mdic.end())//seek가 base.end()와 같다면 검색 조건에 맞는 요소가 없음
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }

    //반복자의 간접 연산의 결과는 보관한 요소 형식 pair<string,Member *>
    delete (*seek).second; //pair의 second는 값인 회원 개체 소멸
    mdic.erase(seek);
    cout<<"삭제하였습니다."<<endl;
}

void App::FindMember()const //회원 검색    
{
    cout<<"검색할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();    
    CMIter seek = mdic.find(id); //map의 find 메서드에 키로 보관된 요소 찾기    
    if(seek == mdic.end())//seek가 base.end()와 같다면 검색 조건에 맞는 요소가 없음
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }
    Member *member = (*seek).second;
    member->View();    
}
void App::ListAll()const //전체 보기
{
    CMIter seek = mdic.begin();
    CMIter end = mdic.end();
    Member *member = 0;    

    //반복자를 사용하여 차례대로 회원의 정보를 출력
    for(  ; seek != end ; ++seek)
    {
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        member->View();
    }
}

App::~App()
{
    MIter seek = mdic.begin();
    MIter end = mdic.end();
    Member *member = 0;

    for(  ; seek != end ; ++seek)
    {
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        delete member;
    }
}