ทุกครั้งที่มีการใช้คำว่า RAII ผู้คนกำลังพูดถึง deconstruction แทนการกำหนดค่าเริ่มต้น ฉันคิดว่าฉันมีความเข้าใจพื้นฐานสิ่งที่อาจหมายถึง แต่ฉันไม่แน่ใจ นอกจากนี้: C ++ เป็นภาษา RAII เดียวหรือไม่ Java หรือ C # /. NET เป็นอย่างไร
ทุกครั้งที่มีการใช้คำว่า RAII ผู้คนกำลังพูดถึง deconstruction แทนการกำหนดค่าเริ่มต้น ฉันคิดว่าฉันมีความเข้าใจพื้นฐานสิ่งที่อาจหมายถึง แต่ฉันไม่แน่ใจ นอกจากนี้: C ++ เป็นภาษา RAII เดียวหรือไม่ Java หรือ C # /. NET เป็นอย่างไร
คำตอบ:
การได้มาซึ่งทรัพยากรคือการเตรียมใช้งานหมายความว่าวัตถุควรดูแลตัวเองเป็นแพ็กเกจที่สมบูรณ์และไม่คาดหวังว่าโค้ดอื่นจะบอกอินสแตนซ์ "เดี๋ยวก่อนคุณจะต้องทำความสะอาดในเร็ว ๆ นี้ - โปรดเรียบร้อยในตอนนี้" มันมักจะหมายความว่ามีบางสิ่งที่มีความหมายในตัวทำลายล้าง นอกจากนี้ยังหมายความว่าคุณเขียนคลาสโดยเฉพาะเพื่อจัดการทรัพยากรโดยรู้ว่าภายใต้สถานการณ์ที่คาดเดายากบางอย่างเช่นข้อยกเว้นที่ถูกโยนทิ้งไป
สมมติว่าคุณต้องการเขียนโค้ดบางอย่างที่คุณจะเปลี่ยนเคอร์เซอร์ windows ไปเป็นเคอร์เซอร์รอ (นาฬิกาทรายโดนัทที่ไม่ทำงาน ฯลฯ ) ทำสิ่งของของคุณแล้วเปลี่ยนกลับ และพูดด้วยว่า "การทำสิ่งของของคุณ" อาจทำให้เกิดข้อยกเว้น วิธีของ RAII ในการทำเช่นนั้นคือการสร้างคลาสที่ ctor ตั้งค่าเคอร์เซอร์เพื่อรอซึ่งวิธีการ "ของจริง" วิธีหนึ่งทำในสิ่งที่คุณต้องการและ Dtor ตั้งเคอร์เซอร์กลับ ทรัพยากร (ในกรณีนี้สถานะเคอร์เซอร์) จะเชื่อมโยงกับขอบเขตของวัตถุ เมื่อคุณได้รับทรัพยากรที่คุณเริ่มต้นวัตถุ คุณสามารถพึ่งพาวัตถุที่ถูกทำลายได้หากมีการโยนข้อยกเว้นและนั่นหมายความว่าคุณสามารถวางใจได้ในการทำความสะอาดทรัพยากร
ใช้ RAII finally
ดีหมายความว่าคุณไม่จำเป็นต้อง แน่นอนมันขึ้นอยู่กับการทำลายล้างซึ่งคุณไม่สามารถทำได้ใน Java คุณจะได้รับการจัดเรียงของการทำลายที่กำหนดใน C # และ VB.NET using
กับ
RAII ส่วนหนึ่งเกี่ยวกับการตัดสินใจเมื่อวัตถุรับผิดชอบการล้างข้อมูลของตัวเอง - กฎที่ว่าวัตถุนั้นจะรับผิดชอบหากและเมื่อการเริ่มต้นตัวสร้างเสร็จสมบูรณ์ ความสมมาตรของการเริ่มต้นและการล้างข้อมูลคอนสตรัคเตอร์และ destructor หมายความว่าทั้งสองมีความสัมพันธ์ใกล้ชิดกัน
จุดหนึ่งของ RAII คือเพื่อให้มั่นใจในความปลอดภัยยกเว้น - แอปพลิเคชันยังคงสอดคล้องกันในตัวเองเมื่อมีการโยนข้อยกเว้น ตั้งแต่แรกเห็นสิ่งนี้ไม่สำคัญ - เมื่อข้อยกเว้นทำให้เกิดขอบเขตออกตัวแปรท้องถิ่นในขอบเขตนั้นจำเป็นต้องถูกทำลาย
แต่จะเกิดอะไรขึ้นถ้าการโยนข้อยกเว้นเกิดขึ้นภายในตัวสร้าง
วัตถุไม่ได้ถูกสร้างอย่างสมบูรณ์ดังนั้นจึงไม่สามารถถูกทำลายได้อย่างปลอดภัย ตัวสร้างควรมีบล็อกลองตามที่จำเป็นเพื่อให้แน่ใจว่ามีการล้างข้อมูลที่จำเป็นใด ๆ เสร็จสิ้นก่อนที่จะทำการยกเว้น เมื่อข้อยกเว้นแพร่กระจายออกไปนอกขอบเขตที่วัตถุถูกสร้างขึ้นจะไม่มีการเรียก destructor เนื่องจากวัตถุไม่ได้ถูกสร้างขึ้นตั้งแต่แรก
พิจารณาเฉพาะสิ่งก่อสร้างสำหรับข้อมูลสมาชิกภายในวัตถุที่ถูกทำลาย หากหนึ่งในนั้นเกิดข้อยกเว้นรหัสคอนสตรัคเตอร์หลักของคุณจะไม่ทำงานเลย - แต่โค้ดบางตัวที่เป็นส่วนหนึ่งโดยนัยของคอนสตรัคเตอร์นั้นจะมี สมาชิกที่สร้างสำเร็จจะถูกทำลายโดยอัตโนมัติ สมาชิกใด ๆ ที่ไม่ได้ถูกสร้างขึ้น (รวมถึงสมาชิกที่โยนข้อยกเว้น) ไม่ได้
ดังนั้นโดยทั่วไป RAII เป็นนโยบายที่รับรองว่าสิ่งใดก็ตามที่ได้รับการก่อสร้างอย่างสมบูรณ์จะถูกทำลายในเวลาที่เหมาะสมโดยเฉพาะอย่างยิ่งเมื่อมีข้อยกเว้นเกิดขึ้นและวัตถุใด ๆ ก็ตามที่ถูกสร้างขึ้นอย่างสมบูรณ์ วัตถุที่สร้างขึ้นซึ่งคุณไม่สามารถรู้วิธีทำความสะอาดได้อย่างปลอดภัย) ทรัพยากรที่ปันส่วนยังเป็นอิสระ และงานจำนวนมากเป็นแบบอัตโนมัติดังนั้นโปรแกรมเมอร์จึงไม่ต้องกังวลกับเรื่องนี้มากนัก