具有不同数据类型或参数的不同函数的函数指针

时间:2017-01-04 04:59:14

标签: c++ function-pointers

我有这个代码使用函数指针指向3函数sum,subtract,mul。它运作良好。但现在的问题是我的函数具有不同的no.of参数和不同的数据类型。如何实现这一点。

int add(int a, int b)
{
    cout<<a+b;
}
int subtract(int a, int b)
{
    cout<<a-b;
}
int mul(int a, int b)
{
    cout<<a*b;
}

int main()
{

    int (*fun_ptr_arr[])(int, int) = {add, subtract, mul};
    unsigned int ch, a = 15, b = 10,c=9;
    ch=2;
    if (ch > 4) return 0;

    (*fun_ptr_arr[ch])(a, b);

    return 0;
}

3 个答案:

答案 0 :(得分:0)

简单的答案是,从技术上讲,你无法做到这一点。您可以使用数组作为所有这些函数的输入进行一些操作,但您仍然必须确切知道要传递给每个函数的内容。从软件工程的角度来看,你不应该这样做 - 我建议你看一下这里很好的答案:C++ Function pointers with unknown number of arguments

答案 1 :(得分:0)

如果您有以下功能

int f1(int i);
int f2(int i, int j);

您可以定义像这样的通用函数类型

typedef int (*generic_fp)(void);

然后初始化你的函数数组

generic_fp func_arr[2] = {
    (generic_fp) f1,
    (generic_fp) f2
};

但是你必须将这些功能强制转换

int result_f1 = ((f1) func_arr[0]) (2);
int result_f2 = ((f2) func_arr[1]) (1, 2);

显然,它看起来不是构建程序的好方法

为了使代码看起来更好一点,你可以定义宏

#define F1(f, p1) ((f1)(f))(p1)
#define F2(f, p1, p2) ((f2)(f))(p1, p2)

int result_f1 = F1(func_arr[0], 2);
int result_f2 = F2(func_arr[1], 1, 2);

修改

忘记提及,你还必须为每种类型的函数定义一个类型

typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params

然后将存储的指针转换为这些类型

int result_f1 = ((fi) func_arr[0]) (2);
int result_f2 = ((fii) func_arr[1]) (1, 2);

这是一个完整的例子

#include <iostream>

typedef int (*generic_fp)(void);
typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params

#define F1(f, p1) ((fi)(f))(p1)
#define F2(f, p1, p2) ((fii)(f))(p1, p2)

int f1(int i);
int f2(int i, int j);

int main()
{

    generic_fp func_arr[2] = {
        (generic_fp) f1,
        (generic_fp) f2
    };

    int result_f1_no_macro = ((fi) func_arr[0]) (2);
    int result_f2_no_macro = ((fii) func_arr[1]) (1, 2);


    int result_f1_macro = F1(func_arr[0], 2);
    int result_f2_macro = F2(func_arr[1], 1, 2);

    std::cout << result_f1_no_macro << ", " << result_f2_no_macro << std::endl;
    std::cout << result_f1_macro << ", " << result_f2_macro << std::endl;

    return 0;
}

int f1(int i)
{
    return i * 2;
}

int f2(int i, int j)
{
    return i + j;
}

上面的代码产生以下输出

4, 3
4, 3

答案 2 :(得分:0)

使用对象实现所需行为的略有不同的方法。为了获得真正通用的解决方案,我们需要使用Interfaces。 拆除数据和操作,即分开保存。

//Interface which describes any kind of data.
struct IData
{
        virtual ~IData()
        {
        }
};

//Interface which desribes any kind of operation
struct IOperation
{
        //actual operation which will be performed
        virtual IData* Execute(IData *_pData) = 0;

        virtual ~IOperation()
        {
        }
};

现在,每个操作都知道它所处理的数据类型,并且只会期望这种数据。

struct Operation_Add : public IOperation
{
            //data for operation addition.
            struct Data : public IData
            {
                    int a;
                    int b;
                    int result;
            };

            IData* Execute(IData *_pData)
            {
                    //expected data is "Operation_Add::Data_Add"
                    Operation_Add::Data *pData = dynamic_cast<Operation_Add::Data*>(_pData);
                    if(pData == NULL)
                    {
                            return NULL;
                    }

                    pData->result = pData->a + pData->b;
                    return pData;
            }
};

struct Operation_Avg : public IOperation
{
            //data for operation average of numbers.
            struct Data : public IData
            {
                    int a[5];
                    int total_numbers;
                    float result;
            };

            IData* Execute(IData *_pData)
            {
                    //expected data is "Operation_Avg::Data_Avg"
                    Operation_Avg::Data *pData = dynamic_cast<Operation_Avg::Data*>(_pData);
                    if(pData == NULL)
                    {
                            return NULL;
                    }

                    pData->result = 0.0f;
                    for(int i = 0; i < pData->total_numbers; ++i)
                    {
                            pData->result += pData->a[i];
                    }
                    pData->result /= pData->total_numbers;
                    return pData;
            }
};

这里是操作处理器,CPU。

struct CPU
{
            enum OPERATION
            {
                    ADDITION = 0,
                    AVERAGE
            };

            Operation_Add m_stAdditionOperation;
            Operation_Avg m_stAverageOperation;
            map<CPU::OPERATION, IOperation*> Operation;

            CPU()
            {
                    Operation[CPU::ADDITION] = &m_stAdditionOperation;
                    Operation[CPU::AVERAGE] = &m_stAverageOperation;
            }
};

<强>示例:

    CPU g_oCPU;

    Operation_Add::Data stAdditionData;
    stAdditionData.a = 10;
    stAdditionData.b = 20;

    Operation_Avg::Data stAverageData;
    stAverageData.total_numbers = 5;
    for(int i = 0; i < stAverageData.total_numbers; ++i)
    {
            stAverageData.a[i] = i*10;
    }

    Operation_Add::Data *pResultAdd = dynamic_cast<Operation_Add::Data*>(g_oCPU.Operation[CPU::ADDITION]->Execute(&stAdditionData));
    if(pResultAdd != NULL)
    {
            printf("add = %d\n", pResultAdd->result);
    }

    Operation_Avg::Data *pResultAvg = dynamic_cast<Operation_Avg::Data*>(g_oCPU.Operation[CPU::AVERAGE]->Execute(&stAverageData));
    if(pResultAvg != NULL)
    {
            printf("avg = %f\n", pResultAvg->result);
    }