2017-09-15 98 views
-2

我是相当新的C和C++。我有任务(这是更多的练习)将给定的c模块更改为C++。为此,我必须首先理解c文件。函数指针阵列:无效**铸造

我有两个具体的问题,但我想在短期内勾勒的功能部件。我尝试使用通用标识符。的C代码

摘录:

有其提供的功能来注册回调代理。 Broker在各自的数组中保存不同类型的回调。

首先,他们宣布了几个函数指针到指定回调:

typedef bool (*ReadRequestCallback_tpf) (param1 a, param2 b, param3 c); 
typedef bool (*ReadResponseCallback_tpf) (param4 a, param5 b); 
typedef bool (*WriteRequestCallback_tpf) (param6 a, param7 b, param8 c); 
... 

然后,他们做了数组为每种类型的持有注册的回调:

ReadRequestCallback_tpf ReadRequest_apf [MaxReadRequest]; 
ReadResponseCallback_tpf ReadResponse_apf [MaxReadResponse]; 
WriteRequestCallback_tpf WriteRequest_apf [MaxWriteRequest]; 

有考虑到职能注册新的回调:

void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){ 
    AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf); 
} 
void RegisterReadResponseCallback_v (ReadResponseCallback_tpf callback_pf){ 
    AddCallback_v((void**)ReadResponse_apf, (void*) callback_pf); 
} 
void RegisterWriteRequestCallback_v (WriteRequestCallback_tpf callback_pf){ 
    AddCallback_v((void**)WriteRequest_apf, (void*) callback_pf); 
} 

的签名是这样的:

void AddCallback_v (void* Array_apv[], void* function_pf) 

我的问题:

  1. (void**) array_apf真的void* array_apv? 因此,一个“函数指针阵列”的至铸造“空隙指向void指针”等于“空隙指针数组空隙指针的”? 因为它的工作原理,似乎是这样。但我真的不明白这一点。

  2. 当试图将它(或部分)更改为C++,是否使用模板,而不是投给(无效*)更好的办法?

这是我第一次来这里。我希望我能解释我的问题。如果有事需要澄清,请告诉我。

此致和预先感谢您

+0

C和C++不是同一种语言,您实际使用哪一种? – Barmar

+0

实际的代码是用C编写的。每个代码片断都用C编写。将来,它应该用C++编写。 – DanK0904

+1

而不是数组,你可以尝试一个std :: function的向量 –

回答

1

C代码实际上是坏的。而任何指针的任何对象可以转换指向void,这是不适合函数指针真。此外,也不能保证一个指针指向一个函数可以重新解释作为中C.一个指针到空隙这意味着函数

void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){ 
    AddCallback_v((void**)ReadRequest_apf, (void*) callback_pf); 
} 

在许多方面被破坏,包括它打破严格的别名。它是如此错误,它伤害。

这样做的目的显然是有一个名为AddCallback_v的泛型函数,该函数获取一个指向回调数组的指针和一个新的回调函数,但是C不能保证这样就可以工作!

在C中,实现代码的正确方法是将有Readrequest_apf等是通用阵列指针到功能;将被强制转换回ReadRequestCallback_tpf等人打电话给他们,即

typedef bool (*GenericCallback_tpf)(); 

GenericCallback_tpf ReadRequest_apf[MaxReadRequest]; 

void AddCallback_v(GenericCallback_tpf callback_array[]); 

void RegisterReadRequestCallback_v (ReadRequestCallback_tpf callback_pf){ 
    AddCallback_v(ReadRequest_apf, (GenericCallback_tpf)callback_pf); 
} 

之前以及在调用时:

((ReadRequestCallback_tpf)ReadRequest_apf[i])(param1, param2, param3); 

在C++中,你会使用仿函数的向量每个这些*_apf;因此不需要投射。

1
  1. 当一个阵列被传递给函数,它的自动转换的指针的第一个元素。所以在函数声明中,TYPE array[]相当于TYPE *array。因此,void *array[]相当于void **array

  2. 模板的目的之一是避免在泛型函数中使用void *类型,因为在使用指针时编译器无法确保您将其转换回原始类型。所以是的,模板通常是比采用void*参数的函数更好的解决方案。