ดีใจที่คุณโพสต์ข้อความนี้เป็นคำถาม :)
ฉันพยายามจะบอกว่า destructors finally
นั้นแตกต่างจากความคิด:
- Destructors สำหรับการปล่อยทรัพยากร ( ข้อมูล )
finally
สำหรับการกลับไปที่ผู้โทร ( ตัวควบคุม )
ลองพิจารณาสมมุติว่าใช้โค้ดหลอกนี้
try {
bar();
} finally {
logfile.print("bar has exited...");
}
finally
นี่คือการแก้ปัญหาการควบคุมทั้งหมดและไม่ใช่ปัญหาการจัดการทรัพยากร
มันคงไม่มีเหตุผลที่จะทำเช่นนั้นในผู้ทำลายล้างด้วยเหตุผลหลายประการ:
- ไม่มีสิ่งใดที่ "ได้มา" หรือ "สร้าง"
- ความล้มเหลวในการพิมพ์ไปยังล็อกไฟล์จะไม่ส่งผลให้เกิดการรั่วไหลของทรัพยากรความเสียหายของข้อมูล ฯลฯ (สมมติว่าไฟล์บันทึกการทำงานที่นี่ไม่ได้ถูกป้อนเข้าสู่โปรแกรมอื่น)
- มันถูกต้องตามกฎหมายที่
logfile.print
จะล้มเหลวในขณะที่การทำลาย (แนวคิด) ไม่สามารถล้มเหลว
นี่เป็นอีกตัวอย่างหนึ่งคราวนี้เหมือนกับใน Javascript:
var mo_document = document, mo;
function observe(mutations) {
mo.disconnect(); // stop observing changes to prevent re-entrance
try {
/* modify stuff */
} finally {
mo.observe(mo_document); // continue observing (conceptually, this can fail)
}
}
mo = new MutationObserver(observe);
return observe();
ในตัวอย่างข้างต้นอีกครั้งไม่มีทรัพยากรที่จะได้รับการปล่อยตัว
ในความเป็นจริงfinally
บล็อกกำลังรับทรัพยากรภายในเพื่อให้บรรลุเป้าหมายซึ่งอาจเกิดความล้มเหลว ดังนั้นจึงไม่เหมาะสมที่จะใช้ตัวทำลาย (ถ้ามี Javascript)
ในอีกทางหนึ่งในตัวอย่างนี้:
b = get_data();
try {
a.write(b);
} finally {
free(b);
}
finally
กำลังทำลายทรัพยากร, b
. มันเป็นปัญหาด้านข้อมูล ปัญหาไม่ได้เกี่ยวกับการคืนค่าการควบคุมไปยังผู้เรียกอย่างชัดเจน แต่เป็นการหลีกเลี่ยงการรั่วไหลของทรัพยากร
ความล้มเหลวไม่ใช่ตัวเลือกและไม่ควรเกิดขึ้น (แนวคิด)
การเปิดตัวทุกครั้งb
จำเป็นต้องจับคู่กับการซื้อกิจการและจำเป็นต้องใช้ RAII
กล่าวอีกนัยหนึ่งเพียงเพราะคุณสามารถใช้เพื่อจำลองทั้งที่ไม่ได้หมายความว่าทั้งสองเป็นหนึ่งและปัญหาเดียวกันหรือว่าทั้งสองเป็นทางออกที่เหมาะสมสำหรับปัญหาทั้งสอง