![](/img/trans.png)
[英]A function that returns a function pointer for functions of different return types
[英]function pointer for different functions with different data types or parameter
我有這個代碼,它使用函數指針指向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;
}
簡單的答案是,從技術上講,你不能這樣做。 您可以使用數組作為所有這些函數的輸入進行一些操作,但您仍然必須確切知道要傳遞給每個函數的內容。 從軟件工程的角度來看,你不應該這樣做 - 我建議你看看這里很好的答案: C ++函數指針,參數數量未知
如果您具有以下功能
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
使用對象實現所需行為的略有不同的方法。 為了獲得真正通用的解決方案,我們需要使用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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.