ทั้ง static_cast และ reinterpret_cast ดูเหมือนจะทำงานได้ดีในการคัดเลือกโมฆะ * ไปยังตัวชี้ประเภทอื่น มีเหตุผลที่ดีที่จะสนับสนุนอีกฝ่ายหรือไม่?
ทั้ง static_cast และ reinterpret_cast ดูเหมือนจะทำงานได้ดีในการคัดเลือกโมฆะ * ไปยังตัวชี้ประเภทอื่น มีเหตุผลที่ดีที่จะสนับสนุนอีกฝ่ายหรือไม่?
คำตอบ:
ใช้static_cast : มันเป็นเพี้ยนที่แคบที่สุดที่อธิบายการแปลงที่ทำที่นี่
มีความเข้าใจผิดว่าการใช้reinterpret_castจะเป็นการจับคู่ที่ดีกว่าเพราะมันหมายถึง“ ไม่สนใจความปลอดภัยของประเภทอย่างสมบูรณ์และเพิ่งส่งจาก A ถึง B”
reinterpret_castแต่นี้ไม่จริงอธิบายผลของการที่ ค่อนข้างreinterpret_castมีความหมายจำนวนมากสำหรับทุกสิ่งที่กล่าวว่า“ การแมปที่ดำเนินการโดยreinterpret_castเป็นการนำมาใช้งานที่กำหนดไว้” [5.2.10.3]
แต่ในกรณีเฉพาะของการคัดเลือกจากvoid*ไปยังT*การทำแผนที่นั้นถูกกำหนดไว้อย่างสมบูรณ์ตามมาตรฐาน กล่าวคือเพื่อกำหนดประเภทให้กับตัวชี้แบบไม่พิมพ์โดยไม่ต้องเปลี่ยนที่อยู่
static_castนี่คือเหตุผลที่จะชอบ
ยิ่งไปกว่านั้นและที่สำคัญกว่านั้นก็คือความจริงที่ว่าการใช้งานทุกครั้งreinterpret_castนั้นอันตรายอย่างยิ่งเพราะมันจะแปลงสิ่งใด ๆ ให้เป็นอย่างอื่น (สำหรับตัวชี้) ในขณะที่static_castมีข้อ จำกัด มากกว่าดังนั้นจึงเป็นการป้องกันที่ดีกว่า สิ่งนี้ได้ช่วยฉันจากข้อผิดพลาดที่ฉันพยายามบังคับให้ตัวชี้ประเภทหนึ่งไปยังอีกประเภทหนึ่งโดยไม่ตั้งใจ
นี่เป็นคำถามที่ยากมาก ในอีกด้านหนึ่ง Konrad สร้างจุดที่ยอดเยี่ยมเกี่ยวกับข้อกำหนด spec สำหรับreinterpret_castแม้ว่าในทางปฏิบัติมันอาจทำสิ่งเดียวกัน ในทางกลับกันถ้าคุณกำลังชี้ไปที่ประเภทตัวชี้ (ตามปกติเมื่อทำการจัดทำดัชนีในหน่วยความจำผ่านอักขระ * *, static_castจะสร้างข้อผิดพลาดของคอมไพเลอร์และคุณจะถูกบังคับให้ใช้reinterpret_castต่อไป
ในทางปฏิบัติฉันใช้reinterpret_castเพราะเป็นการอธิบายถึงเจตนาของการดำเนินการร่าย คุณสามารถสร้างกรณีให้ผู้ปฏิบัติงานรายอื่นเพื่อระบุตัวชี้ reinterprets เท่านั้น (ซึ่งรับประกันที่อยู่เดียวกันที่ส่งคืน) แต่ไม่มีหนึ่งในมาตรฐาน
reinterpret_cast !
ฉันแนะนำให้ใช้นักแสดงที่อ่อนแอที่สุดที่เป็นไปได้เสมอ
reinterpret_castfloatอาจจะใช้ในการส่งตัวชี้ไปยัง ยิ่งการทำลายโครงสร้างมากขึ้นเท่าใดนัก
ในกรณีของchar*ฉันจะใช้นักแสดง c สไตล์จนกว่าเราจะมีบางอย่างreinterpret_pointer_castเพราะมันอ่อนแอและไม่มีอะไรเพียงพอ
float f = *reinterpret_cast<const float*>(&p);
floatซึ่งเป็นเท็จ บรรยากาศการแสดงออกvoid **ไปconst float *แล้วใช้การดำเนินการ dereference (ซึ่งไม่หล่อ) การแปลงไปconst float * float
ความชอบส่วนบุคคลของฉันขึ้นอยู่กับความรู้เรื่องรหัสเช่นนี้:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
หรือ
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
พวกเขาทั้งสองทำสิ่งเดียวกันในตอนท้าย แต่ static_cast ดูเหมือนจะเหมาะสมกว่าในแอพชั้นกลาง, สภาพแวดล้อมของแอปในขณะที่การตีความการส่งซ้ำนั้นดูเหมือนว่าสิ่งที่คุณจะเห็นใน IMHO ระดับต่ำกว่าไลบรารี