7.5 STL의 map 사용

이번에는 STL의 map 사용 방법을 알아보기로 합시다.

map은 key와 value를 쌍으로 구성하는 pair를 보관하는 구조입니다. key를 기준으로 자료를 보관하고 검색하며 실질적으로 보관할 자료를 value입니다. 이처럼 키와 값을 쌍으로 보관하는 자료구조를 사전 컬렉션이라고도 부릅니다. 만약 회원 관리 프로그램에서 회원의 id를 기준으로 map에 보관하면 다음처럼 string을 키로 하고 Member *를 value로 하는 pair를 보관합니다.

#include <map>
using std::map;
using std::pair;
typedef map<string,Member *> Mdic;

여기에서는 map을 사용하는 방법을 두 가지 방법으로 나누어 설명할게요. 첫 번째 방법은 insert, find, erase, iterator를 사용하는 방법이고 두 번째 방법은 인덱스 연산자를 사용하는 방법입니다.

map을 사용하는 방법을 설명하기 위한 프로그램은 두 방법 모두 회원 관리 프로그램으로 하겠습니다.

먼저 두 방법에 공통으로 사용할 회원과 프로토 타이핑을 합시다. 프로젝트를 생성한 후에 공통으로 사용할 파일(3.1.1 참고)을 추가하세요.

회원 클래스는 아이디와 이름을 멤버로 갖게 간단히 구현하기로 해요.

//Member.h
#pragma once
#include "ehglobal.h"
class Member
{
    //아이디를 주요 키로 할 거예요.
    const string id;
    string name;
public:
    //생성자에서 회원 개체의 정보를 입력받기로 합시다.
    Member(string id,string name);
    //멤버 필드에 접근할 수 있는 접근자를 제공하세요.
    string GetID()const;
    string GetName()const;
    //회원 정보를 출력하는 기능도 제공하세요.
    void View()const;
};

회원 클래스의 구체적 구현은 별다른 설명은 하지 않을게요.

Member::Member(string id,string name):id(id)
{
    this->name = name;
}
string Member::GetID()const
{
    return id;
}
string Member::GetName()const
{
    return name;
}
void Member::View()const
{
    cout<<"아이디:"<<id<<" 이름:"<<name<<endl;
}

회원 관리 프로그램의 프로토 타이핑도 같습니다. 여기에서는 map에 회원 보관, 삭제, 검색, 전체 보기를 제공할 거예요. 앞에서 작성했던 도서 관리 프로그램과 매우 유사합니다.

map을 사용하려면 map 파일을 포함하세요. 알고리즘도 필요합니다.

#include <map>
#include <algorithm>

map과 pair를 사용할 거예요.

using std::map;
using std::pair;

키를 회원 ID로 할 것이므로 ID 형식인 string을 key 형식으로 보관할 Member *를 값으로 타입 지정하세요.

typedef map<string, Member *> MDic;

App 클래스를 만드세요.

class App
{
map을 멤버 필드로 추가해야겠죠. 
    MDic mdic;
public:    
    void Run();
    ~App();
private:
    int SelectMenu();
    void AddMember(); //회원 추가
    void RemoveMember();//회원 삭제
    void FindMember()const; //회원 검색    
    void ListAll()const; //전체 보기
};

프로토 타이핑을 구현합시다.

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() //회원 추가
{    
}
void App::RemoveMember()//회원 삭제
{
}
void App::FindMember()const //회원 검색    
{
}
void App::ListAll()const //전체 보기
{
}
App::~App()
{
}

진입점 main을 작성하세요. App 개체 생성한 후 사용자와 상호 작용을 담당하는 Run 메서드 호출한 후에 소멸하는 순서입니다.

int main()
{
    App *app = new App();
    app->Run();
    delete app;
    return 0;
}

현재까지 작성한 코드입니다.

//ehglobal.h
#pragma once
#pragma warning(disable:4996)
#include <string>
using std::string;
#include <iostream>
using std::cout;
using std::cin;
using std::ostream;
using std::endl;
#include <conio.h>
#include <windows.h>
enum keydata
{
    NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,ESC
};
//공통적으로 사용할 정적 메서드를 캡슐화한 클래스
class ehglobal
{
public:
    static void clrscr();//화면을 지우는 메서드
    static void timeflow(int millisecond); //원하는 시간동안 지연시키는 메서드
    static int getnum();//정수를 입력받는 메서드
    static string getstr();//문자열을 입력받는 메서드
    static int getkey();//기능 키를 입력받는 메서드
private:
    ehglobal(void){ }//개체를 생성하지 못하게 하기 위해 private으로 접근 지정
    ~ehglobal(void){}
};

//ehglobal.cpp
#include "ehglobal.h"
void ehglobal::clrscr()//화면을 지우는 메서드
{
    system("cls");
}
void ehglobal::timeflow(int millisecond) //원하는 시간동안 지연시키는 메서드
{
    Sleep(millisecond);
}

int ehglobal::getnum()//정수를 입력받는 메서드
{
    int num;
    char buf[255+1];
    cin.getline(buf,255);
    cin.clear();
    sscanf(buf,"%d",&num);
    return num;
}

string ehglobal::getstr()//문자열을 입력받는 메서드
{
    char buf[255+1];
    cin.getline(buf,255);
    cin.clear();
    return buf;
}

int ehglobal::getkey()//기능 키를 입력받는 메서드
{
    int key = getch();

    if(key == 27) //ESC를 누를 때의 key 값이 27임
    {
        return ESC;
    }
    if(key == 0) //기능 키를 눌렀을 때는 getch의 반환값이 0임
    {
        //어떤 기능 키를 눌렀는지 확인하려면 getch를 다시 호출해야 함
        //사용자에게 다시 키를 입력받는 것은 아님
        key = getch();
        switch(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;
        case 67: return F9;    case 68: return F10;
        }
    }
    return NO_DEFINED; //열거되지 않은 키를 눌렀을 때
}
//Member.h
#pragma once
#include "ehglobal.h"
class Member
{
    const string id;
    string name;
public:
    Member(string id,string name);
    string GetID()const;
    string GetName()const;
    void View()const;
};
//Member.cpp
#include "Member.h"
Member::Member(string id,string name):id(id)
{
    this->name = name;
}
string Member::GetID()const
{
    return id;
}
string Member::GetName()const
{
    return name;
}
void Member::View()const
{
    cout<<"아이디:"<<id<<" 이름:"<<name<<endl;
}
//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()const; //회원 검색    
    void ListAll()const; //전체 보기
};
//App.cpp
#include "App.h"
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() //회원 추가
{    
}
void App::RemoveMember()//회원 삭제
{
}
void App::FindMember()const //회원 검색    
{
}
void App::ListAll()const //전체 보기
{
}
App::~App()
{
}
//Program.cpp
#include "App.h"
int main()
{
    App *app = new App();
    app->Run();
    delete app;
    return 0;
}