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运算符上? 成员函数可以被看作是类 ...
随机推荐
- 洛谷 P5853 - [USACO19DEC]Tree Depth P(生成函数+背包)
洛谷题面传送门 神仙题. 首先考虑一个点的深度是什么,注意到对于笛卡尔树而言直接从序列的角度计算一个点的深度是不容易的,因为这样会牵扯到序列中多个元素,需要 fixed 的东西太多,计算起来太复杂了. ...
- nginx负均
Nginx负载均衡详解 上一篇中我说啦nginx有哪些中负载均衡算法.这一结我就给如果操作配置的给大家做详细说明下. 首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后 ...
- MybatisPlus入门程序
参考资料:MybatisPlus官网 环境搭建 创建数据库 CREATE DATABASE `mybatisplus` USE `mybatisplus` CREATE TABLE `user ...
- 【模板】滑动窗口最值(单调队列)/洛谷P1886
题目链接 https://www.luogu.com.cn/problem/P1886 题目大意 有一个长为 \(n\) 的序列 \(a\) ,以及一个大小为 \(k\) 的窗口.现在这个从左边开始向 ...
- Shell【常用知识总结】
一.常用知识总结 1.特殊变量($0,@,#,*,?) $0:当前脚本的文件名. $n:n是一个数字,表示第几个参数. $#:传递给脚本或函数的参数个数. $*:传递给脚本或函数的所有参数.当被双引号 ...
- MediaPlayer详解
[1]MediaPlayer 详细使用细则 [2]MediaPlayer使用详解_为新手准备 [3]MediaPlayer 概览
- Output of C++ Program | Set 17
Predict the output of following C++ programs. Question 1 1 #include <iostream> 2 using namespa ...
- [学习总结]5、Android的ViewGroup中事件的传递机制(二)
下面是第一篇的连接 Android的ViewGroup中事件的传递机制(一) 关于onInterceptTouchEvent和onTouchEvent的详细解释. 1 public class Mai ...
- Java操作csv文件
以前就一直很想搞懂一个问题就是java如何读取和写入csv文件,现在要花时间总结一波. 主要使用的javaCSV.jar javaCSV API:http://javacsv.sourceforge. ...
- vue-cli4脚手架搭建一
涉及内容 html css javascript node.js npm webpack 2.9.6是常用版本 vue-cli4是基于webpack的 webpack是基于node ...