假设我的课程myClass
定义如下:
template<typename Type> class myClass {
public:
Type* pParent;
void (Type::*func_exe) ();
void execute();
};
我想将它用作函数fGiveMeYourClass
的参数,它使用它来调用它的成员函数execute
void fGiveMeYourClass ( ?myClass? ){
..?.. ->execute();
}
因为我不关心Type
实际上在这个模板中是什么,并且只想要这个类的成员函数指针,所以我可以使用类似typedef来接受该成员函数 - 指针作为fGiveMeYourClass
我已经尝试过,但我的服务似乎失败了:
template <typename Type> typedef void(myClass<Type>::*pMyClassExec)();
void fGiveMeYourClass(pMyClassExec pointerToMemberFunction);
有没有其他方法可以实现,或者我做错了什么?
答案 0 :(得分:0)
这可能很复杂,但我认为您正在努力实现/尝试以下内容:
template <typename Type>
using Func = void (myClass<Type>::*)();
template <typename Type>
void fGiveMeYourClass(Func<Type> fptr )
{
}
如果我理解正确,最简单和简单的方式来获取指向成员函数的指针将是:
template <typename Type>
void fGiveMeYourClass(const myClass<Type>& x)
{
(x.*x.func_exe)();
}
答案 1 :(得分:0)
感谢Alan Stokes对此评论的评论,他发布了我的问题:
您可以将execute声明为非模板化基类中的虚函数,并传递指向基类的指针/引用
这解决了我的问题。
如果有人对此感兴趣: 我需要这个来实现一个类,它可以传递给我的游戏引擎的一部分,让引擎自动执行给定事件的自定义代码片段(测试函数?),例如:当用户按下游戏中的“调试测试功能”按钮时。然而,它确实还有许多其他应用程序
以下是我目前为这些打包命令使用的代码:
class VE_COMMAND_PABA;
class VE_STANDARD_COMMAND;
template <typename ReturnValueType, typename Param1Type, typename Param2Type> class VE_FUNC_COMMAND;
template <typename ParentClassType, typename ReturnValueType, typename Param1Type, typename Param2Type> class VE_DERIVED_FUNC_COMMAND;
class VE_COMMAND_PABA {
public:
enum VE_COMMAND_TYPE {
VE_CT_STANDARD,
VE_CT_FUNC,
VE_CT_DERIVED
} paba_type;
virtual void execute() = 0;
virtual void Release() = 0;
};
class VE_STANDARD_COMMAND : public VE_COMMAND_PABA {
private:
public:
enum VE_STANDARD_COMMAND_TYPE {
VE_SCT_BOOL_TOGGLE,
VE_SCT_INCREMENT,
VE_SCT_DECREMENT,
VE_SCT_SET_INT,
VE_SCT_SET_FLOAT,
VE_SCT_SET_BOOL
} type;
bool* pBOOL;
int* pINT;
float* pFLOAT;
bool params_allocated;
int* set_int;
float* set_float;
bool* set_bool;
VE_COMMAND_PABA* command_exe; // <- REFERENCE TO BASE CLASS
void execute();
void Release(){
if(this->command_exe != nullptr) this->command_exe->Release();
if(this->type == VE_SCT_SET_BOOL && this->params_allocated) delete this->set_bool;
if(this->type == VE_SCT_SET_FLOAT && this->params_allocated) delete this->set_float;
if(this->type == VE_SCT_SET_INT && this->params_allocated) delete this->set_int;
delete this; // bye bye ...
};
};
template <typename ReturnValueType, typename Param1Type, typename Param2Type> class VE_FUNC_COMMAND : public VE_COMMAND_PABA {
public:
enum VE_FUNC_COMMAND_TYPE {
VE_FCT_FUNC,
VE_FCT_FUNC_PARAM,
VE_FCT_FUNC_TWO_PARAM,
} type;
Param1Type* pParam1;
Param2Type* pParam2;
Param1Type** lpParam1;
Param2Type** lpParam2;
bool params_allocated;
ReturnValueType (*func_exe) ();
ReturnValueType (*func_param_exe) (Param1Type parameter);
ReturnValueType (*func_two_param_exe) (Param1Type parameter1, Param2Type parameter2);
void Release(){
if(params_allocated){
if(pParam1 != nullptr) free(pParam1);
if(pParam2 != nullptr) free(pParam2);
}
if(this->command_exe != nullptr) this->command_exe->Release();
delete this; // bye bye...
};
VE_COMMAND_PABA* command_exe; // <- REFERENCE TO BASE CLASS
void execute(){
switch(this->type){
case VE_FCT_FUNC:
this->func_exe();
break;
case VE_FCT_FUNC_PARAM:
this->func_param_exe((*(this->pParam1)));
break;
case VE_FCT_FUNC_TWO_PARAM:
this->func_two_param_exe((*(this->pParam1)), (*(this->pParam2)));
break;
default:
DebugBreak();
break;
};
if(this->command_exe != nullptr){
this->command_exe->execute();
}
};
};
template <typename ParentClassType, typename ReturnValueType, typename Param1Type, typename Param2Type> class VE_DERIVED_FUNC_COMMAND : public VE_COMMAND_PABA {
public:
enum VE_DERIVED_FUNC_COMMAND_TYPE {
VE_DFCT_FUNC,
VE_DFCT_FUNC_PARAM,
VE_DFCT_FUNC_TWO_PARAM,
} type;
Param1Type* pParam1;
Param2Type* pParam2;
Param1Type** lpParam1;
Param2Type** lpParam2;
bool params_allocated;
ParentClassType* pParent;
ParentClassType** lpParent;
ReturnValueType (ParentClassType::*child_func_exe) ();
ReturnValueType (ParentClassType::*child_param_exe) (Param1Type parameter);
ReturnValueType (ParentClassType::*child_func_two_param_exe) (Param1Type parameter1, Param2Type parameter2);
void Release(){
if(params_allocated){
if(pParam1 != nullptr) free(pParam1);
if(pParam2 != nullptr) free(pParam2);
}
if(this->command_exe != nullptr) this->command_exe->Release();
delete this; // bye bye ...
};
VE_COMMAND_PABA* command_exe; // <- REFERENCE TO BASE CLASS
void execute(){
switch(this->type){
case VE_DFCT_FUNC:
if(this->pParent != nullptr){
(this->pParent->*this->child_func_exe)();
}else{
((*(this->lpParent))->*this->child_func_exe)();
}
break;
case VE_DFCT_FUNC_PARAM:
if(this->pParent != nullptr){
(this->pParent->*this->child_param_exe)((*(this->pParam1)));
}else{
((*(this->lpParent))->*this->child_param_exe)((*(this->pParam1)));
}
break;
case VE_DFCT_FUNC_TWO_PARAM:
if(this->pParent != nullptr){
(this->pParent->*this->child_func_two_param_exe)((*(this->pParam1)), (*(this->pParam2)));
}else{
((*(this->lpParent))->*this->child_func_two_param_exe)((*(this->pParam1)), (*(this->pParam2)));
}
break;
default:
DebugBreak();
break;
};
if(this->command_exe != nullptr){
this->command_exe->execute();
}
};
};