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运算符上? 成员函数可以被看作是类 ... 
随机推荐
- Linux非root安装Python3以及解决SSL问题
			说明 接上一篇. [Linux]非root安装Python3及其包管理 上一篇虽然成功安装了Python3及一些常用的模块,但因为一直装不上SSL模块,导致一些包无法安装,尝试了不少方法都失败了(网上 ... 
- 安装octave详解
			1. 一些可以替换的库(可跳过) 默认的库安装libblas.dll.OpenBLAS-v2.6.0-0-54e7b37_dynamicarch_nt4(自动检测CPU类型) 在目录下<your ... 
- 搭建简单的SpringCloud项目一:注册中心和公共层
			注:笔者在搭建途中其实遇见不少问题,统一放在后面的文章说明,现在的搭建是测试OK的. GitHub:https://github.com/ownzyuan/test-cloud 后续:搭建简单的Spr ... 
- 『学了就忘』Linux文件系统管理 — 64、磁盘配额的配置步骤
			目录 1.手工建立一个5GB的分区 2.建立需要做限制的三个用户 3.在分区上开启磁盘配额功能 4.建立磁盘配额的配置文件 5.开始设置用户和组的配额限制 6.启动和关闭配额 7.磁盘配额的查询 8. ... 
- 学习java 6.30
			学习内容:Java的运算符与C中类似,虽是类似,还是有点区别,在这里详细说明一下,即字符以及字符串的+操作,字符的+操作执行后需要赋值给表达式中数据范围最大的类型, 字符串的+操作,当+中有字符串,则 ... 
- day07 Linux配置修改
			day07 Linux配置修改 昨日回顾 1.系统目录 /etc :系统配置目录 /bin-> /usr/bin :保存常用命令的目录 /root :超级管理员目录 /home :普通管理员目录 ... 
- Netty之Channel*
			Netty之Channel* 本文内容主要参考**<<Netty In Action>> ** 和Netty的文档和源码,偏笔记向. 先简略了解一下ChannelPipelin ... 
- Spark(二十)【SparkSQL将CSV导入Kudu】
			目录 SparkSql 将CSV导入kudu pom 依赖 scala 代码 启动脚本 SparkSql 将CSV导入kudu pom 依赖 <properties> <spark. ... 
- Vue相关,vue.nextTick
			vue中有一个较为特殊的API,nextTick.根据官方文档的解释,它可以在DOM更新完毕之后执行一个回调,用法如下: // 修改数据 vm.msg = 'Hello' // DOM 还没有更新 V ... 
- Fragment放置后台很久(Home键退出很长时间),返回时出现Fragment重叠解决方案
			后来在google查到相关资料,原因是:当Fragment长久不使用,系统进行回收,FragmentActivity调用onSaveInstanceState保存Fragment对象.很长时间后,再次 ... 
