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. nginx_location

    Nginx location 配置语法 1. location [ = | ~ | ~* | ^~ ] uri { ... } 2. location @name { ... } location 配 ...

  2. 学习java的第十六天

    一.今日收获 1.完成了手册第二章没有验证完成的例题 2.预习了第三章的算法以及for语句与if语句的用法 二.今日难题 1.验证上出现问题,没有那么仔细. 2.第二章还有没有完全理解的问题 三.明日 ...

  3. 从jvm字节码指令看i=i++和i=++i的区别

    1. 场景的产生 先来看下下面代码展示的两个场景 @Testvoid testIPP() { int i = 0; for (int j = 0; j < 10; j++) { i = i++; ...

  4. C++11的auto自动推导类型

    auto是C++11的类型推导关键字,很强大 例程看一下它的用法 #include<vector> #include<algorithm> #include<functi ...

  5. 编程之美Q1

    题目 和数书页有点类似,就直接数吧 #include<iostream> using namespace std; class q1 { public: size_t func(size_ ...

  6. Lock锁的使用

    在Java多线程中,可以使用synchronized关键字实现线程之间的同步互斥,在jdk1.5后新增的ReentrantLock类同样可达到此效果,且在使用上比synchronized更加灵活. 观 ...

  7. Java 8实现BASE64编解码

    Java一直缺少BASE64编码 API,以至于通常在项目开发中会选用第三方的API实现.但是,Java 8实现了BASE64编解码API,它包含到java.util包.下面我会对Java 8的BAS ...

  8. C++ default constructor | Built-in types

    Predict the output of following program? 1 #include <iostream> 2 using namespace std; 3 4 int ...

  9. vue-cli2嵌入html

    1.使用iframe <!-- 相对路径/绝对路径 --> <iframe src="../../../static/zsw.html"></ifra ...

  10. 【Linux】【Services】【NetFileSystem】Samba

    1. 简介 1.1. 背景:case is initiative by 某windows无良人事,需求是需要一整块4T的硬盘,由于ESXi5最大支持一块盘是2T大小,而且不可以使用windows动态卷 ...