freeeyes 发表于 2010-12-30 18:17:55

关于函数指针的应用

这两天用到了一个需要使用指针回调的地方。以前用函数指针,函数必须是静态的。对于类实例的函数指针,以前没有写过。于是查了点资料,找到了方法,但是没有boost的bind好使,不过代码较为简单,简单的满足一下应该足够了。
在这里记录一下,以后说不定有用
#include "stdafx.h"

class CFunData
{
public:
        CFunData(int nBase) {m_nBase = nBase; };
        ~CFunData() {};

        void Run(int nRet)
        {
                printf("base(%d), All(%d) OK!\n", m_nBase, m_nBase + nRet);
        }
private:
        int m_nBase;
};

class CFPoint
{
public:
        typedef void (CFunData::*FuncP)(int);
        FuncP   m_FuncP;
        CFunData* m_pFunData;

public:
        CFPoint() { m_pFunData = NULL; };
        ~CFPoint() {};

        bool Bind(CFunData* pFunData, FuncP pFn)
        {
                m_pFunData = pFunData;
                m_FuncP = pFn;

                return true;
        };

        void Run(int nData)
        {
                if(m_pFunData != NULL)
                {
                        (m_pFunData->*m_FuncP)(nData);
                }
        }
};

//void (CFunData::*FuncP)(int);
//FuncP = &CFunData::Run;
//(FunData.*FuncP)(10);

int _tmain(int argc, _TCHAR* argv[])
{
        CFunData FunData1(10);
        CFunData FunData2(20);
        CFPointFPoint1;
        CFPointFPoint2;

        FPoint1.Bind(&FunData1, &CFunData::Run);
        FPoint1.Run(20);

        FPoint2.Bind(&FunData2, &CFunData::Run);
        FPoint2.Run(15);
        getchar();

        return 0;
}




运行测试结果:
base(10), All(30) OK!
base(20), All(35) OK!

ztenv 发表于 2011-1-17 15:14:06

不错,不知道有没有什么影响;

featherwit 发表于 2011-1-19 15:27:02

本帖最后由 featherwit 于 2011-1-19 15:28 编辑

我觉得这样实现基本没啥问题,简单明了,效率也很高。
另外正好想起来前段时间弄个一个命令调用的小东西。和这个需求不同,我那个是要求一个全局的类实例调用若干个函数,主要是执行不同命令用的。
简单写下,是这么个意思。
class CUserClass
{
public:
    struct FolkFunction
    {
      virtual int operator() ( /*in and out paras*/ ) = 0;
        //static const keyvaluetype key_;
    };

    typedef boost::shared_ptr<FolkFunction> FolkFunctionPtr;
    typedef std::map<std::string, FolkFunctionPtr> FolkFunction_Colls;
   

protected:
   FolkFunction_Colls m_folkmap;

    template<typename FuncName>
    void RegisterFunctions(FuncName);
...
};
//把这个类singleton化

template<typename FuncName>
inline void CUserClass::RegisterFunctions(FuncName)
{
    m_folkmap.insert(std::make_pair(FuncName::name_, FolkFunctionPtr(new FuncName())));
}

struct HelpFunc :
    public CUserClass::FolkFunction
{
    virtual int operator() ( /*in and out paras*/ )
    {
        //do somthing
    }
    //static const keyvaluetype key_;
};
那个keyvaluetype是随便写的,根据我那边的需要写用的是string,就是命令对应函数,然后传一个参数列表到函数相应函数里面。
这东西的好处是别人实现其他的执行命令比较容易,注册的时候直接register(仿函数名称)就可以了。而且可以根据实际需要做一些他需要的初始化工作。比如在仿函数里面加上一些成员变量神马的。
至于效率...虽然可以不用template,有其他的实现方式...总之玩意儿效率肯定是不高就是了。

ps:这段时间去外地出差...我发誓我再也不出差了...

freeeyes 发表于 2011-1-19 18:40:41

非常好,呵呵,如果能分装成一个例子就更好了。
页: [1]
查看完整版本: 关于函数指针的应用