我对c和c ++很新。我有一个任务(更多的是练习)将给定的c模块更改为c ++。为此,我必须先了解c文件。
我有两个具体问题,但我想简要介绍一下这部分功能。我尝试使用通用标识符。
c代码摘录:
有一个Broker提供注册回调的函数。 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);
}
AddCallback_v
的签名就像:
void AddCallback_v (void* Array_apv[], void* function_pf)
我的问题:
(void**) array_apf
真的是void* array_apv
吗?
因此,'void-pointer指向void-pointer'的'函数指针数组'的转换等于'void指针指向void-pointer数组'?
既然它有效,它似乎就是这样。但我真的不明白。
当尝试将其(或部分)更改为c ++时,使用模板而不是强制转换为(void *)是一种更好的方法吗?
这是我第一次来这里。我希望,我可以解释我的问题。如果需要澄清某些事情,请告诉我。
亲切的问候并提前感谢
答案 0 :(得分:1)
当一个数组传递给一个函数时,它会自动转换为指向第一个元素的指针。因此,在函数声明中,TYPE array[]
等同于TYPE *array
。因此,void *array[]
相当于void **array
。
模板的一个目的是避免对通用函数使用void *
类型,因为编译器无法确保在将其转换回原始类型时使用指针。所以,模板通常是比采用void*
参数的函数更好的解决方案。
答案 1 :(得分:1)
C代码实际上已被破坏。虽然任何指向任何对象的指针都可以转换到指向void 的指针,但对于指向函数的指针,这不是真的。此外,无法保证指向函数的指针可以重新解释作为C中的指向void的指针。这意味着函数
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
中的每一个使用仿函数向量;因此不需要演员阵容。