c++使用map保存成员函数地址
note
- 本基于c++11介绍一种使用map保存成员函数地址
- 可避免使用 if 和 switch
- 配置灵活 方便,
- 代码维护效率高
结果:

范例开始
头文件包含
#include <iostream>
#include <map>
#include <algorithm>
必要类型前置声明
class pop_input_ui;
/// 前置声明
typedef void (pop_input_ui::*psend_cmd)();
/// ----------------------------------------------------------------------------
/// @brief: 用于map保存成员函数地址
/// ----------------------------------------------------------------------------
struct st_send_cmd_config_
{
psend_cmd psend_cmd_ = nullptr;
void zero_()
{
psend_cmd_ = nullptr;
}
st_send_cmd_config_()
{
zero_();
}
};
using send_cmd_config = st_send_cmd_config_;
/// 用于保存成员函数
using map_send_cmd = std::map<int , send_cmd_config>;
类的完整定义
/// ----------------------------------------------------------------------------
/// @brief: 通用弹窗
/// ----------------------------------------------------------------------------
class pop_input_ui
{
public:
/// ----------------------------------------------------------------------------
/// @brief: 发送类型枚举
/// ----------------------------------------------------------------------------
enum en_send_type
{
ksend_type_01 = 1 ,
ksend_type_02 = 2 ,
ksend_type_03 = 3 ,
};
/// ----------------------------------------------------------------------------
/// @brief: 构造函数
/// ----------------------------------------------------------------------------
pop_input_ui()
{
/// ----------------------------------------------------------------------------
/// @brief: 向map中添加item
/// ----------------------------------------------------------------------------
auto map_insert = [&](int map_key, psend_cmd pfunc)
{
send_cmd_config config;
config.psend_cmd_ = pfunc;
std::pair<int, send_cmd_config> map_pair = {map_key, config};
map_send_cmd_.insert(map_pair);
};
/// ----------------------------------------------------------------------------
/// 构建map, 将成员函数地址保存
map_insert(ksend_type_01, &pop_input_ui::send_cmd01_);
map_insert(ksend_type_02, &pop_input_ui::send_cmd02_);
map_insert(ksend_type_03, &pop_input_ui::send_cmd03_);
}
/// ----------------------------------------------------------------------------
/// @brief: 发送命令
/// ----------------------------------------------------------------------------
void send_cmd_(const en_send_type& type)
{
auto find_send_type = map_send_cmd_.find(type);
if (find_send_type == map_send_cmd_.end())
return ;
/// 找到了,则调用
if (nullptr == find_send_type->second.psend_cmd_)
return;
(this->*find_send_type->second.psend_cmd_)();
}
private:
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd02
/// ----------------------------------------------------------------------------
void send_cmd01_()
{
cout << "\n send cmd 01\n";
}
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd02
/// ----------------------------------------------------------------------------
void send_cmd02_()
{
cout << "\n send cmd 02\n";
}
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd03
/// ----------------------------------------------------------------------------
void send_cmd03_()
{
cout << "\n send cmd 03\n";
}
private:
/// 用于保存成员函数地址
map_send_cmd map_send_cmd_;
};
main 函数调用
int main()
{
/// 调用范例
pop_input_ui pop_ui;
/// 调用发送命令01
pop_ui.send_cmd_(pop_input_ui::ksend_type_01);
/// 发送命令02
pop_ui.send_cmd_(pop_input_ui::ksend_type_02);
/// 发送命令03
pop_ui.send_cmd_(pop_input_ui::ksend_type_03);
system("pause");
return 0;
}
完整源码
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
class pop_input_ui;
/// 前置声明
typedef void (pop_input_ui::*psend_cmd)();
/// ----------------------------------------------------------------------------
/// @brief: 用于map保存成员函数地址
/// ----------------------------------------------------------------------------
struct st_send_cmd_config_
{
psend_cmd psend_cmd_ = nullptr;
void zero_()
{
psend_cmd_ = nullptr;
}
st_send_cmd_config_()
{
zero_();
}
};
using send_cmd_config = st_send_cmd_config_;
/// 用于保存成员函数
using map_send_cmd = std::map<int , send_cmd_config>;
/// ----------------------------------------------------------------------------
/// @brief: 通用弹窗
/// ----------------------------------------------------------------------------
class pop_input_ui
{
public:
/// ----------------------------------------------------------------------------
/// @brief: 发送类型枚举
/// ----------------------------------------------------------------------------
enum en_send_type
{
ksend_type_01 = 1 ,
ksend_type_02 = 2 ,
ksend_type_03 = 3 ,
};
/// ----------------------------------------------------------------------------
/// @brief: 构造函数
/// ----------------------------------------------------------------------------
pop_input_ui()
{
/// ----------------------------------------------------------------------------
/// @brief: 向map中添加item
/// ----------------------------------------------------------------------------
auto map_insert = [&](int map_key, psend_cmd pfunc)
{
send_cmd_config config;
config.psend_cmd_ = pfunc;
std::pair<int, send_cmd_config> map_pair = {map_key, config};
map_send_cmd_.insert(map_pair);
};
/// ----------------------------------------------------------------------------
/// 构建map, 将成员函数地址保存
map_insert(ksend_type_01, &pop_input_ui::send_cmd01_);
map_insert(ksend_type_02, &pop_input_ui::send_cmd02_);
map_insert(ksend_type_03, &pop_input_ui::send_cmd03_);
}
/// ----------------------------------------------------------------------------
/// @brief: 发送命令
/// ----------------------------------------------------------------------------
void send_cmd_(const en_send_type& type)
{
auto find_send_type = map_send_cmd_.find(type);
if (find_send_type == map_send_cmd_.end())
return ;
/// 找到了,则调用
if (nullptr == find_send_type->second.psend_cmd_)
return;
(this->*find_send_type->second.psend_cmd_)();
}
private:
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd02
/// ----------------------------------------------------------------------------
void send_cmd01_()
{
cout << "\n send cmd 01\n";
}
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd02
/// ----------------------------------------------------------------------------
void send_cmd02_()
{
cout << "\n send cmd 02\n";
}
/// ----------------------------------------------------------------------------
/// @brief: 发送cmd03
/// ----------------------------------------------------------------------------
void send_cmd03_()
{
cout << "\n send cmd 03\n";
}
private:
/// 用于保存成员函数地址
map_send_cmd map_send_cmd_;
};
int main()
{
/// 调用范例
pop_input_ui pop_ui;
/// 调用发送命令01
pop_ui.send_cmd_(pop_input_ui::ksend_type_01);
/// 发送命令02
pop_ui.send_cmd_(pop_input_ui::ksend_type_02);
/// 发送命令03
pop_ui.send_cmd_(pop_input_ui::ksend_type_03);
system("pause");
return 0;
}
c++使用map保存成员函数地址的更多相关文章
- 直接调用类成员函数地址(用汇编取类成员函数的地址,各VS版本还有所不同)
在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法. ...
- 总结C++中取成员函数地址的几种方法
这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的. 其中, 第4种(汇编)的方法不能在VC6上编译通过. 推荐使用第1,2 ...
- 【转】总结C++中取成员函数地址的几种方法
转自:“http://www.cnblogs.com/nbsofer/p/get_member_function_address_cpp.html” 这里, 我整理了4种C++中取成员函数地址的方法, ...
- C++ 获取类成员函数地址方法 浅析
C语言中可以用函数地址直接调用函数: void print () { printf ("function print"); } typdef void (*fu ...
- c++ STL map容器成员函数
map容器用于查找,设置键值和元素值,输入键值,就能得到元素值.map对象中的元素时刻都是有序的,除非无序插入的.它是用平衡树创建的.查找很快. 函数 描述,注意有r的地方都是不能用it代替的. ma ...
- 介绍了如何取成员函数的地址以及调用该地址:C++
摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...
- 从汇编看c++成员函数指针(三)
前面的从汇编看c++中成员函数指针(一)和从汇编看c++成员函数指针(二)讨论的要么是单一类,要么是普通的多重继承,没有讨论虚拟继承,下面就来看一看,当引入虚拟继承之后,成员函数指针会有什么变化. 下 ...
- C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址
C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...
- 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)
本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上? 成员函数可以被看作是类 ...
随机推荐
- 回文字符串 Manacher
1. Manacher 忘光了,忘光了. 首先将字符串所有字符之间(包括头尾)插入相同分隔符,再在最前方插入另一个分隔符防止越界. 设以 \(s_i\) 为对称中心的回文串中,最长的回文半径为 \(p ...
- Matlab矢量图图例函数quiverkey
Matlab自带函数中不包含构造 quiver 函数注释过程,本文参照 matplotlib 中 quiverkey 函数,构造类似函数为 Matlab 中 quiver 矢量场进行标注. quive ...
- zabbix忘记密码——进入数据库修改
登录数据库,选择zabbix数据库 查看数据库里面的表 用户和用户密码在users表里面 将你想设置的密码进行MD5加密处理: 更新密码即可: update users set passwd=&quo ...
- 一个好用的快速安装lnmp环境包lnmp1-6
一个好用的快速安装lnmp环境包lnmp1-6 地址:https://lnmp.org/tag/lnmp1-6/
- 多线程高级篇1 — JUC — 只弄到处理高并发集合问题
1.线程池 1.1).什么是线程池? 池( pool ),就是一个容器,所以线程池就是把多个线程对象放到一个容器中 1.2).如何创建线程池? 先来了解几个常识 Executor -- 这是一个接口( ...
- LeetCode一维数组的动态和
一维数组的动态和 题目描述 给你一个数组 nums.数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]...nums[i]). 请返回 nums 的动态和. 示例 1: ...
- 在idea的java开发中字符串length()方法获取长度与赋值不符的问题
最近在开发中用到length()方法获取中文字符串的长度,发现获得的长度与实际不符.比如个String类型赋值为"中",但获取长度却是2. 这让我百思不得其解,后来突然想起来我在研 ...
- ps精修
1.磨皮方法: a,, 添加高斯模糊后,按住alt键新建图层蒙版,设置前景色为白色,用画笔在脸上雀斑的位置涂抹,注意脸轮廓位置不要涂抹.最后添加曲线提亮 b. 添加蒙尘和划痕后,后面上面的一样
- vmware使用nat连接配置
一.首先查看自己的虚拟机服务有没有开启,选择电脑里面的服务查看: 1.计算机点击右键选择管理 2.进入管理选择VM开头的服务如果没有开启的话就右键开启 二.虚拟机服务开启后就查看本地网络虚拟机的网 ...
- Linux基础命令---elinks文本浏览器
elinks elinks指令是一个纯文本格式的浏览器,支持颜色.表格.鼠标.菜单操作. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora. 1.语法 ...