將指標轉換為物件時使用或不參考有什么區別?
void someClass::method(){
xTaskCreatePinnedToCore(someTaskHandler,"SerialNowTaskTX",XT_STACK_MIN_SIZE*3,this,4,&taskHandleTX,0); // passing 'this' to task handler
}
void someTaskHandler(void *p){
SerialNow_ SerialNow = *((SerialNow_*)p); // compile but not working properly
SerialNow_ &SerialNow = *((SerialNow_*)p); // compile and working
SerialNow_ *SerialNow = ((SerialNow_*)p); // compile and working but I preffer . over ->
int A = SerialNow.somethingA;
SerialNow.somethingB();
while(1){
}
vTaskDelete(NULL);
}
uj5u.com熱心網友回復:
初步意見
首先,請記住,轉換void*
指標在 C 中是一件相當危險的事情,如果指向的物件與您要轉換的型別不兼容,則可能是 UB。
與其在括號之間進行類似 C 的強制轉換,不如使用更明確的 C 強制強制轉換,這可以更好地顯示危險程度。如果 p 是多型基型別,則更喜歡使用更安全的dynamic_cast
. 否則使用 astatic_cast
來避免一些常見的錯誤。僅在不得已的情況下使用reinterpret_cast
,但您必須真正確定自己在做什么。
你的說法有什么不同?
如果我們假設 p 是指向與SerialNow_
此兼容的型別的有效指標,那么您的不同陳述句的含義是:
SerialNow_ SerialNow = *((SerialNow_*)p);
第一個復制 p 指向的物件。如果稍后更改 b 指向的物件的內容,則不會對物件產生影響SerialNow
。請記住,如果 p 指向的物件不是 aSerialNow_
而是子類, 則可能會發生切片。
SerialNow_ &SerialNow = *((SerialNow_*)p);
第二個創建一個參考,該參考指向 p 所指向的物件。你可以SerialNow
把它當作一個物件來使用,但實際上它指的是與 p 指向的物件相同的物件:
SerialNow_ *SerialNow = ((SerialNow_*)p);
第三個創建指向 p 指向的物件的指標:
第二和第三方面的多型性。如果 p 指向的物件不是 aSerialNow_
而是一個子型別,那么多型就會起作用,即如果你呼叫一個虛函式,就會呼叫對應于物件真正運行時型別的那個。
uj5u.com熱心網友回復:
情況1
在這里,我們考慮以下宣告:
SerialNow_ SerialNow = *((SerialNow_*)p);
這里void*
p
將(使用顯式型別轉換)強制轉換為SerialNow_*
. 接下來,使用型別SerialNow_*
為物件的結果取消參考該結果。*operator
SerialNow_
最后,生成SerialNow_
的物件用作初始化器SerialNow
來初始化左側命名的物件。新初始化的物件SerialNow
是原始物件的副本。這意味著,如果您對其進行更改,SerialNow
則不會影響 . 指向的原始物件p
。
案例2
在這里,我們考慮以下宣告:
SerialNow_ &SerialNow = *((SerialNow_*)p);
在這種情況下,大部分程序與情況 1 相同,只是這次SerialNow
是結果物件的別名。這與第一種情況的不同之處僅在于,在第一種情況下SerialNow
,左側的物件是原始物件的副本,而SerialNow
左側的物件是對原始物件的左值參考。這意味著,如果您對其進行更改,SerialNow
將會影響 指向的原始物件p
。
案例3
在這里,我們考慮以下宣告:
SerialNow_ *SerialNow = ((SerialNow_*)p);
這里void*
p
被轉換為SerialNow_*
. 但是,與案例 1 和案例 2 不同,生成的指標不會被取消參考SerialNow
。因此,這里左側命名的物件是從顯式型別轉換產生的指標初始化的。
此外,SerialNow
是由顯式型別轉換產生的指標的副本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/480145.html
上一篇:我無法訪問結構陣列上的欄位
下一篇:使用參考列印char值