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保存成员函数地址的更多相关文章

  1. 直接调用类成员函数地址(用汇编取类成员函数的地址,各VS版本还有所不同)

    在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法. ...

  2. 总结C++中取成员函数地址的几种方法

    这里, 我整理了4种C++中取成员函数地址的方法, 第1,2,4种整理于网上的方法, 第3种cdecl_cast是我自己想到的. 其中, 第4种(汇编)的方法不能在VC6上编译通过. 推荐使用第1,2 ...

  3. 【转】总结C++中取成员函数地址的几种方法

    转自:“http://www.cnblogs.com/nbsofer/p/get_member_function_address_cpp.html” 这里, 我整理了4种C++中取成员函数地址的方法, ...

  4. C++ 获取类成员函数地址方法 浅析

    C语言中可以用函数地址直接调用函数:   void print ()   {   printf ("function print");   }   typdef void (*fu ...

  5. c++ STL map容器成员函数

    map容器用于查找,设置键值和元素值,输入键值,就能得到元素值.map对象中的元素时刻都是有序的,除非无序插入的.它是用平衡树创建的.查找很快. 函数 描述,注意有r的地方都是不能用it代替的. ma ...

  6. 介绍了如何取成员函数的地址以及调用该地址:C++

    摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...

  7. 从汇编看c++成员函数指针(三)

    前面的从汇编看c++中成员函数指针(一)和从汇编看c++成员函数指针(二)讨论的要么是单一类,要么是普通的多重继承,没有讨论虚拟继承,下面就来看一看,当引入虚拟继承之后,成员函数指针会有什么变化. 下 ...

  8. C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...

  9. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

随机推荐

  1. 回文字符串 Manacher

    1. Manacher 忘光了,忘光了. 首先将字符串所有字符之间(包括头尾)插入相同分隔符,再在最前方插入另一个分隔符防止越界. 设以 \(s_i\) 为对称中心的回文串中,最长的回文半径为 \(p ...

  2. Matlab矢量图图例函数quiverkey

    Matlab自带函数中不包含构造 quiver 函数注释过程,本文参照 matplotlib 中 quiverkey 函数,构造类似函数为 Matlab 中 quiver 矢量场进行标注. quive ...

  3. zabbix忘记密码——进入数据库修改

    登录数据库,选择zabbix数据库 查看数据库里面的表 用户和用户密码在users表里面 将你想设置的密码进行MD5加密处理: 更新密码即可: update users set passwd=&quo ...

  4. 一个好用的快速安装lnmp环境包lnmp1-6

    一个好用的快速安装lnmp环境包lnmp1-6 地址:https://lnmp.org/tag/lnmp1-6/

  5. 多线程高级篇1 — JUC — 只弄到处理高并发集合问题

    1.线程池 1.1).什么是线程池? 池( pool ),就是一个容器,所以线程池就是把多个线程对象放到一个容器中 1.2).如何创建线程池? 先来了解几个常识 Executor -- 这是一个接口( ...

  6. LeetCode一维数组的动态和

    一维数组的动态和 题目描述 给你一个数组 nums.数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]...nums[i]). 请返回 nums 的动态和. 示例 1: ...

  7. 在idea的java开发中字符串length()方法获取长度与赋值不符的问题

    最近在开发中用到length()方法获取中文字符串的长度,发现获得的长度与实际不符.比如个String类型赋值为"中",但获取长度却是2. 这让我百思不得其解,后来突然想起来我在研 ...

  8. ps精修

    1.磨皮方法: a,, 添加高斯模糊后,按住alt键新建图层蒙版,设置前景色为白色,用画笔在脸上雀斑的位置涂抹,注意脸轮廓位置不要涂抹.最后添加曲线提亮 b. 添加蒙尘和划痕后,后面上面的一样

  9. vmware使用nat连接配置

    一.首先查看自己的虚拟机服务有没有开启,选择电脑里面的服务查看: 1.计算机点击右键选择管理  2.进入管理选择VM开头的服务如果没有开启的话就右键开启  二.虚拟机服务开启后就查看本地网络虚拟机的网 ...

  10. Linux基础命令---elinks文本浏览器

    elinks elinks指令是一个纯文本格式的浏览器,支持颜色.表格.鼠标.菜单操作. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.   1.语法       ...