7.5.2 STL map 사용 방법 2

앞에서는 STL의 map을 insert, erase, find 멤버 메서드와 반복자를 사용하는 방법을 살펴보았습니다. 이번에는 인덱스 연산을 사용하는 방법으로 회원 관리 프로그램을 구현해 보아요.

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

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

AddMember 메서드부터 구현합시다.

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

추가할 회원 아이디를 입력받습니다.

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

키를 인자로 인덱스 연산을 사용하면 보관한 값을 구할 수 있습니다. 만약 없다면 인덱스 연산에 사용한 키와 0을 값으로 하는 pair를 보관한 후에 pair의 second를 반환합니다. 즉 결과는 0이예요.

결과가 0이 아니라면 이미 존재하는 아이디입니다. 메시지를 출력하고 기능을 종료하세요.

    if(mdic[id])
    {
        cout<<"이미 존재하는 아이디입니다."<<endl;
        return;
    }

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

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

키를 인자로 인덱스 연산을 사용한 표현을 대입 연산자 좌항에 두고 대입 연산자 우항에 값을 표현합니다. 따라서 여기에서는 다음처럼 사용할 수 있겠죠.

    mdic[id]=new Member(id,name);    
}

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

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

삭제할 회원 아이디를 입력받습니다.

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

키인 아이디를 인자로 인덱스 연산을 사용하여 값을 얻어오세요.

    Member *member = mdic[id];

만약 값이 0이면 보관한 회원 개체가 없는 것입니다. 메시지 출력 후에 기능을 종료하세요.

    if(member==0)
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }    

보관한 회원 개체를 소멸하세요.

    delete member;

그리고 키를 인자로 인덱스 연산을 표현한 것을 대입 연산자 좌항에 표현하여 0을 대입하세요.

    mdic[id]=0;
    cout<<"삭제하였습니다."<<endl;
}

검색 기능에서도 인덱스 연산을 사용할 것입니다. 앞에서 FindMember 메서드는 상수화 멤버 메서드로 정의하였는데 map의 인덱스 연산은 상수화 멤버가 아닙니다. 불가피하게 FindMember 메서드를 상수화가 아닌 멤버 메서드로 수정하세요. 물론 헤더 파일도 수정하셔야겠죠.

class App
{
   ...중략...
    void FindMember(); //회원 검색
    ...중략...
};

회원 검색 기능을 구현합시다.

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

검색할 회원 아이디를 입력받으세요.

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

키인 아이디를 인자로 인덱스 연산을 사용하여 값을 얻어오세요.

    Member *member = mdic[id];

만약 값이 0이면 보관한 회원 개체가 없는 것입니다. 메시지 출력 후에 기능을 종료하세요.

    if(member==0)
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }    

회원 정보를 출력하세요.

    member->View();    
}

전체 보기 메서드인 ListAll을 구현합시다.

void App::ListAll()const //전체 보기
{

반복자를 사용하여 차례대로 회원 정보를 출력합니다.

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

여기에서는 인덱스 연산으로 값이 존재하지 않는 검색을 하였을 때 검색에 사용한 키와 0을 값인 pair를 보관합니다. 따라서 반복자의 간접 연산의 second로 값을 얻어온 후 0인지 판별하세요.

그리고 0이 아닐 때만 회원 정보를 출력하세요.

        if(member)
        {
            member->View();
        }
    }
}

이제 소멸자를 구현합시다. 소멸할 때도 0이 아닐 때만 회원 개체를 소멸하세요.

App::~App()
{
    MIter seek = mdic.begin();
    MIter end = mdic.end();
    Member *member = 0;
        
    for(  ; seek != end ; ++seek)
    {
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        if(member)
        {
            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();    
    if(mdic[id])
    {
        cout<<"이미 존재하는 아이디입니다."<<endl;
        return;
    }
    cout<<"회원 이름을 입력하세요."<<endl;
    string name = ehglobal::getstr();    
    mdic[id]=new Member(id,name);    
}

void App::RemoveMember()//회원 삭제
{
    cout<<"삭제할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();
    
    Member *member = mdic[id];
    if(member==0)    
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }    
    delete member;
    mdic[id]=0;
    cout<<"삭제하였습니다."<<endl;
}

void App::FindMember() //회원 검색    
{
    cout<<"검색할 회원 아이디를 입력하세요."<<endl;
    string id = ehglobal::getstr();    
    Member *member = mdic[id];
    if(member==0)
    {
        cout<<"존재하지 않는 아이디입니다."<<endl;
        return;
    }    
    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는 보관한 회원 개체
        if(member)
        {
            member->View();
        }
    }
}
App::~App()
{
    MIter seek = mdic.begin();
    MIter end = mdic.end();
    Member *member = 0;
    for(  ; seek != end ; ++seek)
    {
        member = (*seek).second; //pair의 second는 보관한 회원 개체
        if(member)
        {
            delete member;
        }
    }
}

다음은 FindMember메서드를 상수화 멤버 메서드를 비상수화 멤버 메서드로 수정한 App.h 파일 내용입니다. 나머지 코드는 7.5 STL의 map 사용 게시글을 참고하세요.

//App.h
#pragma once
#include "ehglobal.h"
#include "Member.h"
#include <map>
#include <algorithm>
using std::map;
using std::pair;
typedef map<string, Member *> MDic;
class App
{
    MDic mdic;
public:    
    void Run();
    ~App();
private:
    int SelectMenu();
    void AddMember(); //회원 추가
    void RemoveMember();//회원 삭제
    void FindMember(); //회원 검색    
    void ListAll()const; //전체 보기
};