会用CMap了,其他的基本也就会了,很容易理解。
映射表类(CMap)是MFC集合类中的一个模板类,也称作为“字典”,就像一种只有两列的表格,一列是关键字,一列是数据项,它们是一一对应的。关键字是唯一的,给出一个关键字,映射表类会很快找到对应的数据项。映射表的查找是以哈希表的方式进行的,因此在映射表中查找数值项的速度很快。举个例子来说吧,公司的所有职员都有一个工号和自己的姓名,工号就是姓名的关键字,给出一个工号,就可以很快的找到相应的姓名。映射类最适用于需要根据关键字进行快速检索的场合。
CMapWordToPtr 保存void指针,关键字为WORD
CMapPtrToWord 保存WORD,关键字为void指针
CMapPtrToPtr 保存void指针,关键字为其它void指针
CMapWordToOb 保存CObject指针,关键字为WORD
CMapStringToOb 保存CObject指针,关键字为字符串
CMapStringToPtr 保存void指针,关键字为字符串
CMapStringToString 保存字符串,关键字为字符串
声明:CMap m_SockToUserIDMap;
CMap m_UserIDToSockMap;
赋值:m_SockToUserIDMap[pUserInfo->sSocket] = pszUserID;
m_UserIDToSockMap[pszUserID] = pUserInfo->sSocket;
取值:char *pszUserID = m_SockToUserIDMap[sSock];
SOCKET sSock = m_UserIDToSockMap[pszUserID];
此处略去CMyData的代码。
以下演示CMap的基本用法,其它的也都差不多的用法,只是其中元素变一变。
//定义类型
typedef CTypedPtrMap CMapDataMap;
//定义实例
CMapDataMap m_map;
//添加
CMyData *pData=new CMyData;
m_map.SetAt("abc", pData); //abc对应pData
//再使用abc查找刚才放进去的CMyData
CMyData *pResult=NULL;
if(m_map.Lookup ("abc", pResult))
{
//找到了...
}
//删除
CMyData *pResult=NULL;
if(m_map.Lookup("abc", pResult))
{
m_map.RemoveKey("abc");
delete pResult;pResult=NULL;
}
//删除CMap中所有项
POSITION pos=map.GetStartPosition();
CString szKey="";
CMyData *pData=NULL;
while(pos!=NULL)
{
m_map.GetNextAssoc(pos, szKey, pData);
delete pData;pData=NULL;
}
m_map.RemoveAll();
Map通常是为了查找才使用的,比如你有一个链表List, 其中记录了10000个对象,每个对象都有一个不同的ID.这时,你要查找指定ID的对象,如果使用List,则你必须遍历整个List,看看那个对象的ID相同.随着对象数目的增加,此操作效率将非常低.因此,最后建立一个Map,并进行维护.
CMapMyIDMap;
此时, 你用CMap::Lockup函数就可以很快的找到你要的对象.
建议你看一看有关CMap原理的书籍, 其中又有Hash查找的实现. 如果你不清楚CMap的原理,肯定无法有效的使用CMap
//define a CMap object
CMap g_IDToName;
//Create CMap
void g_CreateClassInfo()
{
char *pszStuName = NULL;
for(int i=0; i<10; i++)
{
pszStuName = new char[28];
sprintf(pszStuName, i%2==0?"linjun%d":"liuxing%d", i);
g_IDToName[i] = pszStuName;
}
}
//show one element
void g_DisplayStuInfo(int nStuID)
{
if(!g_IDToName.IsEmpty())
{
if(g_IDToName.GetCount() < nStuID)
return;
if(NULL != g_IDToName[nStuID])
printf("stuID = %d, Stu Name = %s\n", nStuID, g_IDToName[nStuID]);
}
}
//show all element
void g_DisplayAllClassInfo()
{
for(UINT i=0; i g_DisplayStuInfo(i);
}
//delete a element from CMap
void g_DelElement(int nStuID)
{
char* pszStuName = g_IDToName[nStuID];
if(NULL != pszStuName)
{
delete pszStuName;
pszStuName = NULL;
}
g_IDToName.RemoveKey(nStuID);
}
//add a element to CMap
void g_AddElement(char* pszStuName)
{
char *pNewElement = new char[28];
strcpy(pNewElement, pszStuName);
g_IDToName[g_IDToName.GetCount()] = pNewElement;
}
//release the memory on element
void g_ReleaseElement()
{
if(!g_IDToName.IsEmpty())
{
char *pElement;
int nKey;
POSITION pos = g_IDToName.GetStartPosition();
while(pos != NULL)
{
g_IDToName.GetNextAssoc(pos, nKey, pElement);
if(NULL != (char*)pElement)
{
delete (char*)pElement;
pElement = NULL;
}
g_IDToName.RemoveKey(nKey);
}
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
//init CMap
g_CreateClassInfo();
//display all student infomation
g_DisplayAllClassInfo();
//delete no.5 student
g_DelElement(5);
printf("\nAfter delete no.5 student ID:\n");
g_DisplayAllClassInfo();
//add a student named "esmilepro"
g_AddElement("esmilepro");
printf("\nAfter add a new student:\n");
g_DisplayAllClassInfo();
//release memory
g_ReleaseElement();
}
return nRetCode;
}
阅读(3580) | 评论(0) | 转发(0) |