c++ 普通函数指针与类模板的使用(一)

本文介绍如何使用函数指针和类模板实现一对多调用的功能,通过具体代码示例展示了如何定义支持不同类型函数指针的类模板,并进一步扩展到支持多个函数指针的注册。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        函数指针与类的使用在实际项目中经常会使用,但更多的情况是在类里声明一个类模板的变量,这个类模板实现了包含某种类型的函数指针,同时这个类模板可以进行多个函数指针的注册,这样就可以实现了一对多的调用情况,这个类似于设计模式中的“观察者模式”,即一个动作的发生可以有多个响应。

        下面看一个简单的将函数指针注册到类里的例子,如:
 

#include <stdio.h>
#include <stdlib.h>

class CFunc_ptr
{
    typedef int (*funcProc)(int, int); //声明函数指针,只能针对一种类型
public:
    CFunc_ptr(): m_funcProc(nullptr)
    {
    }

    ~CFunc_ptr()
    {
        m_funcProc = nullptr;
    }

    bool attach(funcProc func)
    {
        m_funcProc = func;
        return true;
    }

    bool detach()
    {
        m_funcProc = nullptr;
        return true;
    }

    int invoke(int a, int b)
    {
        if(m_funcProc != nullptr)
        {
            return m_funcProc(a, b); //函数指针调用
        }
        return 0;
    }
private:
    funcProc m_funcProc;
};

int add(int a, int b)
{
    return a + b;
}

int main()
{
    CFunc_ptr func;
    func.attach(add);
    int ret = func.invoke(3, 6);
    printf("ret = %d\n", ret);

    return 0;
}

这个类很简单,只能支持一种类型的函数指针的注册,如果是不同的类型则需要用到模板了。

#include <stdio.h>
#include <stdlib.h>

template <class R, class T1, class T2>
class CFunction
{
    typedef R (*funcProc)(T1 a, T2 b);
public:
    CFunction(): mFuncProc(nullptr)
    {

    }

    ~CFunction()
    {
        mFuncProc = nullptr;
    }

public:
    bool attach(funcProc func)
    {
        if(mFuncProc != func)
        {
            mFuncProc = func;
            return true;
        }

        return false;
    }

    R invoke(T1 a, T2 b)
    {
        if(mFuncProc != nullptr)
        {
            return mFuncProc(a, b);
        }

    }
private:
    funcProc    mFuncProc;
};

int add(int a, int b)
{
    return a + b;
}

int main()
{
    CFunction<int, int, int> func;
    func.attach(add);
    int ret = func.invoke(5, 5);
    printf("ret = %d\n", ret);
    
    return 0;
}

这里声明了一个类模板,一共 3 个参数,这 3 个参数用来声明一个函数指针,一个参数作为函数的返回值,其他为函数参数。通过这 3 个参数,你可以定义不同类型的函数指针了。而要达到观察者模式那种类型,还需要支持多个函数指针的注册,其实就是要定义函数指针数组,也可以用std库容器,如下最简单的数组形式:

#include <stdio.h>
#include <stdlib.h>

template <class R, class T1, class T2>
class CFunction
{
    typedef R (*funcProc)(T1 a, T2 b);
public:
    CFunction(int maxSize): mCurrentPos(0), mSize(maxSize), mFuncProc(nullptr)
    {
        mFuncProc = new funcProc [mSize];
    }

    ~CFunction()
    {
        mFuncProc = nullptr;
    }

public:
    bool attach(funcProc func)
    {
        if(mFuncProc[mCurrentPos] != func)
        {
            mFuncProc[mCurrentPos] = func;
            mCurrentPos++;
            return true;
        }            

        return false;
    }

    // invoke one by one
    R invoke(T1 a, T2 b)
    {
        for(int i = 0; i < mSize; i++)
        {
            if(mFuncProc[i] != nullptr)
            {
                mFuncProc[i](a, b);
            }            
        }
    }
private:
    int         mCurrentPos; //当前函数指针数组位置
    int         mSize; //最大支持注册个数
    funcProc    *mFuncProc;
};

void add1(int a, int b)
{
    int ret =  a + b;
    printf("in add1 ret = %d\n", ret);
}

void add2(int a, int b)
{
    int ret =  a + b;
    printf("in add2 ret = %d\n", ret);
}

void add3(int a, int b)
{
    int ret =  a + b;
    printf("in add3 ret = %d\n", ret);
}

int main()
{
    CFunction<void, int, int> func(3);
    func.attach(add1);
    func.attach(add2);
    func.attach(add3);
    func.invoke(5, 5);

    return 0;
}

实际项目中会用到宏及模板来定义各种类型,包括参数个数、参数类型。这个下次再贴出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值