MFC中CMap类的用法和原理

news2025/4/25 22:11:34

1、CMap 的原理

CMap 是一个基于哈希表的映射类,它将唯一键映射到对应的值。其内部实现依赖于哈希算法,通过哈希函数将键转换为哈希值,然后将哈希值映射到哈希表中的某个位置。如果多个键的哈希值相同(即哈希冲突),CMap 会使用链表来解决冲突。

1.1关键点

1.1.1 哈希函数:
CMap 使用模板函数 HashKey() 来计算键的哈希值。默认情况下,HashKey() 假设键是一个指针,并将其转换为 DWORD。对于字符串类型(如 LPCSTR 和 LPCWSTR),CMap 提供了专门的哈希函数实现。
如果使用自定义类型作为键,需要提供自己的哈希函数。
1.1.2 哈希表大小:
哈希表的大小会影响性能。如果哈希表太小,可能会导致大量冲突;如果太大,则会浪费内存。可以通过调用 InitHashTable 方法来初始化哈希表并指定其大小。
1.1.3 存储结构:
CMap 内部使用一个哈希表来存储键值对。每个哈希表条目可能是一个链表,用于存储具有相同哈希值的键值对。

2.CMap 的用法

2.1. 定义和初始化

CMap 是一个模板类,需要指定键类型、键的参数类型、值类型和值的参数类型。例如:
下面展示一些 内联代码片

CMap<int, int, CString, CString> myMap; // 键为 int,值为 CString

在使用 CMap 之前,建议调用 InitHashTable 方法初始化哈希表:

myMap.InitHashTable(101); // 哈希表大小为 101

2.2 插入键值对

使用 SetAt 方法插入键值对:

myMap.SetAt(1, _T("Value1"));
myMap.SetAt(2, _T("Value2"));

也可以使用 operator[] 插入或修改键值对:

myMap[3] = _T("Value3");

3. 查找键值对

使用 Lookup 方法查找键对应的值:

CString value;
if (myMap.Lookup(1, value))
{
    // 找到键为 1 的值
    TRACE(_T("Value: %s\n"), value);
}

4. 遍历映射

可以使用 GetStartPosition 和 GetNextAssoc 方法遍历映射中的所有键值对:

POSITION pos = myMap.GetStartPosition();
int key;
CString value;
while (pos != NULL)
{
    myMap.GetNextAssoc(pos, key, value);
    TRACE(_T("Key: %d, Value: %s\n"), key, value);
}

5. 删除键值对

使用 RemoveKey 方法删除指定键的键值对:

myMap.RemoveKey(1); // 删除键为 1 的键值对

也可以使用 RemoveAll 方法清空整个映射:

myMap.RemoveAll();

6. 获取映射的大小

使用 GetSize 或 GetCount 方法获取映射中的元素数量:

int size = myMap.GetSize();
TRACE(_T("Map size: %d\n"), size);

3.注意事项

3.1 键的唯一性:
CMap 要求键是唯一的。如果尝试插入一个已经存在的键,SetAt 方法会覆盖原有的值。
3.2 自定义键类型:
如果使用自定义类型作为键,需要提供哈希函数和比较函数。默认情况下,CMap 使用 HashKey 函数计算哈希值,并使用 operator== 比较键。
3.3 性能优化:
选择合适的哈希表大小可以提高性能。哈希表大小通常是质数,可以减少冲突。
3.4 序列化:
如果需要将 CMap 对象序列化到文件,可以使用 Serialize 方法。CMap 会自动序列化其所有元素。
示例代码:

#include <afx.h>
#include <afxtempl.h>
#include <iostream>

int main()
{
    CMap<int, int, CString, CString> myMap;
    myMap.InitHashTable(101);

    // 插入键值对
    myMap.SetAt(1, _T("Value1"));
    myMap.SetAt(2, _T("Value2"));
    myMap[3] = _T("Value3");

    // 查找键值对
    CString value;
    if (myMap.Lookup(2, value))
    {
        std::wcout << L"Key 2: " << value.GetString() << std::endl;
    }

    // 遍历映射
    POSITION pos = myMap.GetStartPosition();
    int key;
    while (pos != NULL)
    {
        myMap.GetNextAssoc(pos, key, value);
        std::wcout << L"Key: " << key << L", Value: " << value.GetString() << std::endl;
    }

    // 删除键值对
    myMap.RemoveKey(1);
    myMap.RemoveAll();

    return 0;
}

以上就是MFC中CMap类的简单用法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2325594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

elementplus的el-tabs路由式

在使用 Element Plus 的 el-tabs 组件&#xff0c;实现路由式的切换&#xff08;即点击标签页来切换不同的路由页面&#xff09;。下面是一个基于 Vue 3 和 Element Plus 实现路由式 el-tabs 的基本步骤和示例。 步骤 1: 安装必要的库 在vue3项目安装 Vue Router 和 Element …

数据结构初阶:单链表

序言&#xff1a; 本篇博客主要介绍单链表的基本概念&#xff0c;包括如何定义和初始化单链表&#xff0c;以及如何进行数据的插入&#xff0c;删除和销毁等操作。 1.单链表 1.1 概念与结构 概念&#xff1a;链表是一种非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过…

RabbitMQ高级特性--TTL和死信队列

目录 1.TTL 1.1设置消息的TTL 1.1.1配置交换机&队列 1.1.2发送消息 1.1.3运行程序观察结果 1.2设置队列的TTL 1.2.1配置队列和交换机的绑定关系 1.2.2发送消息 1.2.3运行程序观察结果 1.3两者区别 2.死信队列 2.1 声名队列和交换机 2.2正常队列绑定死信交换机 …

Java后端开发: 如何安装搭建Java开发环境《安装JDK》和 检测JDK版本

文章目录 一、JDK的安装1、 打开 Oracle 官方网址2、点击产品 二、检测JDK是否安装成功以及JDK版本的查看1. 打开命令行窗口检测是否安装成功查看 JDK 版本 一、JDK的安装 1、 打开 Oracle 官方网址 Oracle官网地址:https://www.oracle.com/cn/ 2、点击产品 打开下载的JDK文件…

LabVIEW液压控制系统开发要点

液压控制系统开发需兼顾高实时性、强抗干扰性和安全性&#xff0c;尤其在重工业场景中&#xff0c;毫秒级响应延迟或数据异常都可能导致设备损坏。本文以某钢厂液压升降平台项目为例&#xff0c;从硬件选型、控制算法、安全机制三方面&#xff0c;详解LabVIEW开发中的关键问题与…

MFC添加免费版大漠3.1233

先创建一个MFC工程&#xff0c; 添加dm.dll 方法一&#xff1a;通过类向导-添加类-类型库中的MFC类-文件&#xff0c;选择dm.dll&#xff0c;如果没有"添加类型库中的MFC类"选项就用方法二添加 方法二&#xff1a;添加-新建项-MFC-Active或TypeLib-实现接口位置选…

vue 图片放大到全局

背景&#xff1a; 在vue项目中&#xff0c;el-image组件图片组件用于展示图片&#xff0c;组件自带的属性preview-teleported&#xff0c;设置为true可以控制图片放大到全局 实现效果&#xff1a; 核心代码&#xff1a; //图片地址&#xff1a;BASEUrl /file/ item.file //这…

在rockylinux9.4安装mongodb报错:缺少:libcrypto.so.10文件库

问题点&#xff1a; rockylinux9.4系统环境报错&#xff1a; ./mongod: error while loading shared libraries: libcrypto.so.10: cannot open shared object file: No such file or directory 解决方法&#xff1a; Ps&#xff1a;解压之后&#xff0c;检查mongodb的依赖环境…

【力扣hot100题】(019)旋转图像

比较考验脑子转不转得过来&#xff0c;最好先在纸上画一下图整理思路&#xff0c;不要和我一样上来就无脑套循环。 理解了思路还是好做的&#xff0c;每个小循环转一圈&#xff0c;大循环代表转的第几圈。小循环循环n-2i-1次&#xff0c;大循环循环&#xff08;n1&#xff09;…

06_约束

文章目录 一、是什么二、实体完整性约束2.1、主键约束2.2、主键自增长2.3、唯一约束 三、域完整性约束3.1、非空约束3.2、默认值 四、引用完整性约束 一、是什么 用于限制加入表的数据的类型和规范&#xff0c;约束是添加在列上的&#xff0c;用来约束列的。 分类&#xff1a; …

Seata AT模式的一些常见问题及其源码解析

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。 Seata AT 基于两阶段提交协议的演变&#xff1a; 一阶段&#xff1a;业…

2025年3月29日(matlab -ss -lti)

线性时不变系统&#xff08;LTI系统&#xff09;的定义与核心特性 线性时不变系统&#xff08;Linear Time-Invariant System&#xff09;是信号与系统分析中的基础模型&#xff0c;其核心特性包括线性和时不变性。以下从定义、验证方法和应用场景展开说明&#xff1a; 1. 线性…

网络原理-TCP/IP

网络原理学习笔记&#xff1a;TCP/IP 核心概念 本文是我在学习网络原理时整理的笔记&#xff0c;主要涵盖传输层、网络层和数据链路层的核心协议和概念&#xff0c;特别是 TCP, UDP, IP, 和以太网。 一、传输层 (Transport Layer) 传输层负责提供端到端&#xff08;进程到进…

第五十三章 Spring之假如让你来写Boot——环境篇

Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…

Router [Continuation Settings]

楼上网络CMCC-Wmew&#xff0c;楼下接收不到&#xff0c;可能因为喜好弱&#xff0c;再弄一台路由器中转一下 Router [Continuation Settings] 路由器中续设置 到这里这台K3的路由器设置完成了&#xff0c;作为转发&#xff0c;中续&#xff0c;她还需要设置上游路由器&#…

Zookeeper中的Zxid是如何设计的

想获取更多高质量的Java技术文章&#xff1f;欢迎访问Java技术小馆官网&#xff0c;持续更新优质内容&#xff0c;助力技术成长 Java技术小馆官网https://www.yuque.com/jtostring Zookeeper中的Zxid是如何设计的 如果你们之前学习过 ZooKeeper&#xff0c;你们可能已经了解…

蓝桥云客 岛屿个数

0岛屿个数 - 蓝桥云课 问题描述 小蓝得到了一副大小为 MN 的格子地图&#xff0c;可以将其视作一个只包含字符 0&#xff08;代表海水&#xff09;和 1&#xff08;代表陆地&#xff09;的二维数组&#xff0c;地图之外可以视作全部是海水&#xff0c;每个岛屿由在上/下/左/右…

31天Python入门——第14天:异常处理

你好&#xff0c;我是安然无虞。 文章目录 异常处理1. Python异常2. 异常捕获try-except语句捕获所有的异常信息获取异常对象finally块 3. raise语句4. 自定义异常5. 函数调用里面产生的异常补充练习 异常处理 1. Python异常 Python异常指的是在程序执行过程中发生的错误或异…

浅析Android Jetpack ACC之LiveData

一、Android Jetpack简介 Android官网对Jetpack的介绍如下&#xff1a; Jetpack is a suite of libraries to help developers follow best practices, reduce boilerplate code, and write code that works consistently across Android versions and devices so that develo…

【区块链安全 | 第十五篇】类型之值类型(二)

文章目录 值类型有理数和整数字面量&#xff08;Rational and Integer Literals&#xff09;字符串字面量和类型&#xff08;String Literals and Types&#xff09;Unicode 字面量&#xff08;Unicode Literals&#xff09;十六进制字面量&#xff08;Hexadecimal Literals&am…