CMap은 사전이라고 생각하시면 됩니다.
CArray는 배열이죠.
그래서 첨자에 의해서, 즉 순서를 지정해서 값을 저장하고 읽습니다.
하지만 CMap은 순서가 아니라 키에 의해서 값을 저장하고 읽게 됩니다.
예를 들어서, 영한 사전을 생각해보세요.
boy라는 영어 단어와 소년이라는 해석은 쌍으로 존재할 때 의미가 있습니다.
만약 배열을 쓴다고 하면,
영어 단어 배열과 한글 해석 배열, 이렇게 두개가 필요합니다.
그리고 어떤 영어 단어의 해석을 보고 싶다면
영어 단어 배열에서의 해당 단어 위치를 구하고,
한글 해석 배열의 해당 위치의 해석을 꺼내야 합니다.
하지만 CMap을 사용하면,
키와 값을 한꺼번에 저장하고 읽을 수 있습니다.
boy를 키로 저장하면서 동시에 소년이라는 해석도 값으로써 저장할 수 있죠.
CMap은 이 두개를 한꺼번에 저장하므로 CMap 하나만 있으면 됩니다.
그리고 boy라는 단어의 해석을 알고 싶을 때는,
키가 boy인 값을 Lookup()으로 구하면 됩니다.
이렇게 키와 값으로 구성되는 데이터를 처리할 때 CMap을 사용하며,
키는 CMap 내부에서 해싱 함수를 통해 특별한 값으로 변환하여 내부 인덱스로 사용하게 됩니다.
CMap을 사용해서 변수를 만들 때는 데이터 타입을 4가지 지정해줘야 합니다.
첫번째는 CMap 내부에서 키를 관리할 때 사용하는 데이터 타입이고,
두번째는 코드에서 CMap에게 키를 전달할 때 어떤 타입으로 전달하는지 입니다.
세번째는 CMap 내부에서 값을 관리할 때 사용하는 데이터 타입이고,
네번째는 코드에서 CMap에게 값을 전달할 때 어떤 타입으로 전달하는지 입니다.
CMap my_map;
이렇게 맵을 만들었다면,
이 맵에게 키를 줄 때는 int형(두번째)으로 줄 것이고,
맵 안에서는 키를 int형으로 관리하게 됩니다.
그리고 코드에서 값을 줄 때 double형(네번째)으로 줄 것이고,
이 값을 받아서 맵 안에서는 double형으로 관리하게 됩니다.
맵에 값을 넣을 때는
SetAt() 멤버 함수를 호출합니다.
혹은 배열처럼 [] 연산자를 사용할 수도 있죠.
맵에서 값을 찾을 때는 Lookup()을 사용합니다.
그리고 맵에서 하나의 키와, 그 키의 값을 삭제할 때는 RemoveKey()를 쓰며,
맵에 저장된 모든 키와 그 키들의 값들을 모두 삭제할 때는 RemoveAll()을 씁니다.
맵에 저장된 키-값의 쌍의 갯수를 얻고 싶을 때는 GetCount()를 쓰며,
맵이 비어 있는지 알고 싶을 땐 IsEmpty()를 호출할 수 있습니다.
그리고 맵에 저장된 모든 값들을 순서적으로 한번씩 읽고 싶을 땐,
GetStartPosition()으로 첫 키의 위치를 얻고,
GetNextAssoc()을 반복해서 호출하여 각 키와 값을 얻을 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include "stdafx.h" #include <afxtempl.h> int _tmain( int argc, TCHAR * argv[], TCHAR * envp[]) { int nValue = 0; CString strKey; POSITION pos = NULL; CMap<CString, LPCSTR , int , int > m; /* 1. add key and value */ m.SetAt( "AAA" , 111); m.SetAt( "ABC" , 123); /* 2. lookup key 'AAA' */ if ( m.Lookup( "AAA" , nValue) ) printf ( "find 'AAA' = %d\n" , nValue); else printf ( "no such key\n" ); /* 3. replace key and value */ m.SetAt( "AAA" , 333); if ( m.Lookup( "AAA" , nValue) ) printf ( "find 'AAA' = %d\n" , nValue); else printf ( "no such key\n" ); /* 4. iterate map */ pos = m.GetStartPosition(); while ( pos != NULL ) { m.GetNextAssoc(pos, strKey, nValue); printf ( "%s = %d\n" , strKey.operator LPCTSTR (), nValue); } /* 5. remove 'AAA' key */ m.RemoveKey( "AAA" ); /* 6. iterate map after removing 'AAA' key */ pos = m.GetStartPosition(); while ( pos != NULL ) { m.GetNextAssoc(pos, strKey, nValue); printf ( "%s = %d\n" , strKey.operator LPCTSTR (), nValue); } /* 7. print map count */ printf ( "a saved number of key in map is %d\n" , m.GetCount()); /* 8. remove all existing key pair */ m.RemoveAll(); printf ( "a saved number of key in map is %d\n" , m.GetCount()); return 0; |
출처 - http://www.dreamy.pe.kr/zbxe/CodeClip/18110
매우 편리하고 유용한 MFC 템플릿(Template) 클래스 CMap< CString, LPCTSTR, int, int > 의 사용 주의 사항을 설명 드립니다.
주의사항 |
CMap 사용하기 무척 편리합니다. 특히 스트링(String)맵의 경우 사용용도가 높으나 아래와 같이 오류발생 가능이 있는 코드가 존재하니 주의해서 사용합니다.
올바른 코드
CMap< CString, LPCTSTR, int, int > map; map["One"] = 1; map["Two"] = 2; CString s1 = map["One"]; CString s2 = map["Two"]; CString s3 = map["Three"]; CString s4 = map[ NULL ]; |
문제의 코드
char* sz = "One"; CString s1 = map[ sz ]; sz = NULL; CString s2 = map[ sz ]; |
위의 코드에서는 sz 가 NULL 이 되면 치명적인 오류가 발생할 수 있으니 주의합니다.
(특히 게임 서버에서 사용할 경우에 주의합니다.)
보너스 오류 발생 코드
char* sz = NULL; int len = strlen( sz ); strcmp( sz, "123" ); |
위와 이 strcmp, strlen 등의 함수를 사용할 경우에는 인자가 NULL 이면 프로그램이 다운됩니다.
'C & C++ > C & C++' 카테고리의 다른 글
USES_CONVERSION (0) | 2013.08.02 |
---|---|
레지스트리 시작프로그램 등록/해제 함수 (0) | 2013.05.24 |
CString 특정문자 갯수 구하기 (0) | 2013.02.22 |
MFC 에서 임의의 클래스의 포인터 얻기 (0) | 2012.12.31 |
시간 연산 관련 함수 모음 (0) | 2012.11.28 |
댓글