2017-09-15 93 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*參數的函數更好的解決方案。