在使用C++过程中,有时会遇到这样的场景:函数实现的功能不同,参数类型不同,但参数个数相同,如果频繁调用这些函数,每个函数都手动去调用一次显得特别繁琐,特别是以后新增加类似功能的函数,函数调用的各个地方都要手动去添加对新函数的调用,效率低下,不易维护。
下面例子,使用for循环去调用不同功能函数,方便实用,易于修改:
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <vector>
enum enumType
{
ENUM_TYPE_INT = 1,
ENUM_TYPE_CHAR = 2,
ENUM_TYPE_DOUBLE = 3,
ENUM_TYPE_STRING = 4,
};
union UnionData
{
/** 共用数据
*/
void* m_pCommonData;
/** int类型数据
*/
int* m_pIntData;
/** char类型数据
*/
char* m_pCharData;
/** double类型数据
*/
double* m_pDoubleData;
/** string类型数据
*/
std::string* m_pStringData;
};
class TestFunction;
typedef void(TestFunction::*pFtest)(void*);
struct RCTestType
{
enumType type;
pFtest m_pTestFunction;
};
class TestFunction
{
public:
/** 注册函数
*/
void RegisterFunction(enumType enumType, pFtest pTest)
{
RCTestType testType;
testType.type = enumType;
testType.m_pTestFunction = pTest;
m_typeFunction.push_back(testType);
}
void Scan(UnionData pData, enumType type)
{
for (unsigned i = 0; i < m_typeFunction.size(); i++)
{
const RCTestType& testType = m_typeFunction[i];
if (testType.type == type)
{
(this->*(testType.m_pTestFunction))((void*)&pData);
break;
}
}
}
public:
void ScanIntData(void* p)
{
UnionData* t = (UnionData*)p;
std::cout << "scan int data:" << *(t->m_pIntData)<<std::endl;
}
void ScanDoubleData(void* p)
{
UnionData* t = (UnionData*)p;
std::cout << "scan double data:" << *(t->m_pDoubleData) << std::endl;
}
void ScanCharData(void* p)
{
UnionData* t = (UnionData*)p;
std::cout << "scan char data:" <<*(t->m_pCharData)<< std::endl;
}
void ScanStringData(void* p)
{
UnionData* t = (UnionData*)p;
std::cout << "scan string data:" <<(char*)(t->m_pStringData)<< std::endl;
}
private:
/** 注册函数
*/
std::vector<RCTestType> m_typeFunction;
};
int _tmain(int argc, _TCHAR* argv[])
{
TestFunction test;
test.RegisterFunction(ENUM_TYPE_INT, &TestFunction::ScanIntData);
test.RegisterFunction(ENUM_TYPE_CHAR, &TestFunction::ScanCharData);
test.RegisterFunction(ENUM_TYPE_DOUBLE, &TestFunction::ScanDoubleData);
test.RegisterFunction(ENUM_TYPE_STRING, &TestFunction::ScanStringData);
UnionData data;
data.m_pCommonData = new int(3);
test.Scan(data, ENUM_TYPE_INT);
delete data.m_pCommonData;
data.m_pCommonData = nullptr;
data.m_pCommonData = new double(13.14);
test.Scan(data, ENUM_TYPE_DOUBLE);
delete data.m_pCommonData;
data.m_pCommonData = nullptr;
data.m_pCommonData = new char('y');
test.Scan(data, ENUM_TYPE_CHAR);
delete data.m_pCommonData;
data.m_pCommonData = nullptr;
data.m_pCommonData = ("hello");
test.Scan(data, ENUM_TYPE_STRING);
getchar();
return 0;
}