简体   繁体   English

模板类的成员函数指针

[英]Member function pointer of template class

Assuming I have a class myClass defined as follows: 假设我有一个类myClass定义如下:

template<typename Type> class myClass {

    public:

        Type* pParent;
        void (Type::*func_exe) ();

        void execute();

};

And I want to use it as parameter for a function fGiveMeYourClass , which uses it to call it's member-function execute 我想将其用作函数fGiveMeYourClass参数,该函数使用它来调用其成员函数execute

void fGiveMeYourClass ( ?myClass? ){

    ..?.. ->execute();

}

since I don't care about what Type actually is in this template and only want this classes' member-function-pointer, I'd be fine with something like a typedef to accept that member-function-pointer as parameter of fGiveMeYourClass 因为我不在乎此模板中实际上是什么Type ,而只希望此类的成员函数指针,所以我可以使用像typedef这样的东西来接受该成员函数指针作为fGiveMeYourClass参数

I tried that already but my attepts seemed to fail: 我已经尝试过了,但是我的尝试似乎失败了:

template <typename Type> typedef void(myClass<Type>::*pMyClassExec)();
void fGiveMeYourClass(pMyClassExec pointerToMemberFunction);

Is there any other way this could be achieved or am I doing something wrong? 还有其他方法可以实现吗,或者我做错了什么?

This might be complicated but I think you're trying to achieve/experiment following : 这可能很复杂,但是我认为您正在尝试实现/实验以下目标:

template <typename Type> 
using Func = void (myClass<Type>::*)();


template <typename Type> 
void fGiveMeYourClass(Func<Type> fptr )
{

}

If I understood correctly, the simplest and plain way to get your pointer to member function working would be : 如果我理解正确,那么使指针指向成员函数工作的最简单明了的方法是:

template <typename Type> 
void fGiveMeYourClass(const myClass<Type>& x)
{ 
   (x.*x.func_exe)(); 
}

Thanks to Alan Stokes for this comment he posted on my question: 感谢Alan Stokes的评论,他在我的问题上发布了:

You could declare execute as a virtual function in a non-templated base class, and pass around a pointer/reference to the base 您可以在非模板基类中将execute声明为虚拟函数,并将指针/引用传递给基类

This solved my problem. 这解决了我的问题。

In case it's interesting to someone: I needed this to implement a class that could be passed on to a part of my game-engine to let the engine autonomously execute a custom piece of code ( a test-function? ) at a given event, eg when the user presses the "Debug-test-function"-button in-game. 万一某人感兴趣:我需要它来实现一个类,该类可以传递给我的游戏引擎的一部分,以使引擎在给定事件中自主执行一段自定义代码(测试功能?),例如,当用户在游戏中按下“调试测试功能”按钮时。 It however does have lots of other applications as well 但是它也有很多其他应用程序

Here is the code I use so far for these packaged commands: 这是到目前为止我用于这些打包命令的代码:

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

            }

        };

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM