函数的参数是一个不确定类类型,可以做到吗?
(之前发了一个问题贴,但有点乱了,所以重发一个)
c#的写法:
public delegate TaskResult ConditionDelegate<E>(E entity, GameTime gameTime) where E : Entity;
我想在c++里写一个类似的,于是考虑选择用函数指针,但是参数能是不确定类类型吗(泛型)?
我需要把不同名称,但是参数个数一样的函数做为函数参数传过去。
比如, 我有
void abc (ClassA a, int b)
void bbc(ClassB a,int b)
void bcc (ClassC a, int b)
......等几十个这样的函数,要把他们当参数condition传递给 Execute(ConditionDelegate<T> condition );
那应该怎么写? 有人说用模板,但是模板只能是名称一样的函数。
[解决办法]
模板的功能比你说的强多了。
template <typename Result,typename Arg>
Result exe(Result (*pfun)(Arg,int)){
Result res = pfun(Arg(),3);
return res;
}
int fun(char c, int i){
return i + 3;
}
int main(){
printf("%d",exe(fun));
system("pause");
return 0;
}
[解决办法]
用模板+虚函数可以实现.
实现的效果如下:
[code]
class ClassA {};
class ClassB {};
class ClassC {};
void abc (ClassA a, int b)
{
printf("%s: %d\n", typeid(a).name(), b);
}
void bbc(ClassB a,int b)
{
printf("%s: %d\n", typeid(a).name(), b);
}
void bcc (ClassC a, int b)
{
printf("%s: %d\n", typeid(a).name(), b);
}
int main()
{
CommandPtr pFuncPtr;
ClassA a;
ClassB b;
ClassC c;
pFuncPtr = abc;
pFuncPtr(a, 10);
pFuncPtr = bbc;
pFuncPtr(b, 20);
pFuncPtr = bcc;
pFuncPtr(c, 30);
}
[/code]
相关定义的头文件:
[code]
class ICommand
{
public:
virtual void Execute(void* /* 最好是用 classA, classB, classC 的共同基类 */ pObj, int x) = 0;
virtual ~ICommand() {};
};
template <typename T>
ICommand* MakeCommand(void (*func)(T, int))
{
class TheCommand : public ICommand
{
void (*m_func)(T, int);
public:
TheCommand(void (*func)(T, int)) : m_func(func) {};
public:
virtual void Execute(void* pObj, int x)
{
m_func(*(T*)pObj, x);
}
};
return new TheCommand(func);
}
class CommandPtr
{
ICommand* m_ptr;
public:
CommandPtr() : m_ptr(0) {};
~CommandPtr()
{
if(m_ptr != NULL)
delete m_ptr;
}
public:
template <typename T>
void operator()(T Obj, int x)
{
if(m_ptr == NULL)
return;
m_ptr->Execute((void*)&Obj, x);
}
template <typename T>
CommandPtr& operator=(void (*func)(T, int))
{
if(m_ptr != NULL)
delete m_ptr;
m_ptr = MakeCommand(func);
return *this;
}
};
[/code]
要把它作为参数传递只需要再为 CommandPtr 实现一个拷贝构造函数就可以了.
也可以直接使用 ICommand* 做为参数.