首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

函数的参数是一个不确定类门类,可以做到吗

2013-12-28 
函数的参数是一个不确定类类型,可以做到吗?(之前发了一个问题贴,但有点乱了,所以重发一个)c#的写法:public

函数的参数是一个不确定类类型,可以做到吗?
(之前发了一个问题贴,但有点乱了,所以重发一个)

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* 做为参数.

热点排行