模板类的成员函数指针

时间:2014-12-28 18:17:48

标签: c++ templates member-function-pointers

假设我的课程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);

有没有其他方法可以实现,或者我做错了什么?

2 个答案:

答案 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();

            }

        };

};