RAII คืออะไร ตัวอย่าง?


19

ทุกครั้งที่มีการใช้คำว่า RAII ผู้คนกำลังพูดถึง deconstruction แทนการกำหนดค่าเริ่มต้น ฉันคิดว่าฉันมีความเข้าใจพื้นฐานสิ่งที่อาจหมายถึง แต่ฉันไม่แน่ใจ นอกจากนี้: C ++ เป็นภาษา RAII เดียวหรือไม่ Java หรือ C # /. NET เป็นอย่างไร

คำตอบ:


25

การได้มาซึ่งทรัพยากรคือการเตรียมใช้งานหมายความว่าวัตถุควรดูแลตัวเองเป็นแพ็กเกจที่สมบูรณ์และไม่คาดหวังว่าโค้ดอื่นจะบอกอินสแตนซ์ "เดี๋ยวก่อนคุณจะต้องทำความสะอาดในเร็ว ๆ นี้ - โปรดเรียบร้อยในตอนนี้" มันมักจะหมายความว่ามีบางสิ่งที่มีความหมายในตัวทำลายล้าง นอกจากนี้ยังหมายความว่าคุณเขียนคลาสโดยเฉพาะเพื่อจัดการทรัพยากรโดยรู้ว่าภายใต้สถานการณ์ที่คาดเดายากบางอย่างเช่นข้อยกเว้นที่ถูกโยนทิ้งไป

สมมติว่าคุณต้องการเขียนโค้ดบางอย่างที่คุณจะเปลี่ยนเคอร์เซอร์ windows ไปเป็นเคอร์เซอร์รอ (นาฬิกาทรายโดนัทที่ไม่ทำงาน ฯลฯ ) ทำสิ่งของของคุณแล้วเปลี่ยนกลับ และพูดด้วยว่า "การทำสิ่งของของคุณ" อาจทำให้เกิดข้อยกเว้น วิธีของ RAII ในการทำเช่นนั้นคือการสร้างคลาสที่ ctor ตั้งค่าเคอร์เซอร์เพื่อรอซึ่งวิธีการ "ของจริง" วิธีหนึ่งทำในสิ่งที่คุณต้องการและ Dtor ตั้งเคอร์เซอร์กลับ ทรัพยากร (ในกรณีนี้สถานะเคอร์เซอร์) จะเชื่อมโยงกับขอบเขตของวัตถุ เมื่อคุณได้รับทรัพยากรที่คุณเริ่มต้นวัตถุ คุณสามารถพึ่งพาวัตถุที่ถูกทำลายได้หากมีการโยนข้อยกเว้นและนั่นหมายความว่าคุณสามารถวางใจได้ในการทำความสะอาดทรัพยากร

ใช้ RAII finallyดีหมายความว่าคุณไม่จำเป็นต้อง แน่นอนมันขึ้นอยู่กับการทำลายล้างซึ่งคุณไม่สามารถทำได้ใน Java คุณจะได้รับการจัดเรียงของการทำลายที่กำหนดใน C # และ VB.NET usingกับ


4
ฉันคิดว่านี่คือสิ่งที่คุณได้รับ แต่คุณอาจต้องการเพิ่มเหตุผลที่ Java และ C # ไม่สนับสนุน RAII เป็นเพราะตัวเก็บขยะ ใน C ++ วัตถุท้องถิ่นจะถูกทำลายทันทีที่มันออกนอกขอบเขต ใน Java / C # สิ่งนี้ไม่เป็นความจริง
Jason Baker

การขยายในจุด Jasons เหตุผลที่ Java และ C # ไม่สามารถรับประกันการทำลายในเวลาที่เหมาะสมได้เนื่องจากความเป็นไปได้ของรอบการอ้างอิงซึ่งหมายความว่าเป็นไปไม่ได้ที่จะกำหนดลำดับความปลอดภัยในการเรียกใช้ destructors รอบการอ้างอิงสามารถเกิดขึ้นได้ใน C ++ แต่ความหมายแตกต่างกัน - โปรแกรมเมอร์กลายเป็นผู้รับผิดชอบในการกำหนดลำดับการทำลายและการลบอย่างชัดเจน ความรับผิดชอบนั้นมักถูกบรรจุในตัวทำลายคลาสระดับสูงกว่าเช่นคลาสคอนเทนเนอร์มีหน้าที่ตรวจสอบให้แน่ใจว่ารายการทั้งหมดที่มีอยู่ถูกทำลาย "ความเป็นเจ้าของ" คือกุญแจสำคัญ
Steve314

1
@ Jason นั่นคือสิ่งที่ฉันหมายถึงโดย "การทำลายที่กำหนดขึ้น" - โปรแกรมเมอร์ C ++ รู้ว่าเมื่อใดที่ destructor จะทำงาน
Kate Gregory

ฉันรู้ว่านี่เป็นคำตอบเก่า แต่ฉันก็ยังสับสนอยู่บ้าง ฉันเพิ่งเรียนรู้คำศัพท์และข้อมูลบางอย่างบอกว่าการได้มานั้นควรเกิดขึ้นในตัวสร้าง นั่นไม่สมเหตุสมผลกับฉันและคำตอบนี้ดูเหมือนจะขัดแย้งกับมัน แต่คุณช่วยอธิบายได้ไหม?
ต่อ Johansson

1
@PerJohansson ใช่คุณได้รับใน ctor และคุณปล่อยใน dtor ฉันมุ่งเน้นไปที่จุดที่สอง แต่พวกเขาไปด้วยกัน เมื่อ ctor เสร็จแล้วคุณรู้ว่าคุณมีวัตถุที่ถูกต้อง และคุณรู้ว่าไม่ว่าจะเกิดอะไรขึ้นทรัพยากรจะถูกปล่อยออกมาในเวลาที่เหมาะสม
เคทเกรกอรี่

4

RAII ส่วนหนึ่งเกี่ยวกับการตัดสินใจเมื่อวัตถุรับผิดชอบการล้างข้อมูลของตัวเอง - กฎที่ว่าวัตถุนั้นจะรับผิดชอบหากและเมื่อการเริ่มต้นตัวสร้างเสร็จสมบูรณ์ ความสมมาตรของการเริ่มต้นและการล้างข้อมูลคอนสตรัคเตอร์และ destructor หมายความว่าทั้งสองมีความสัมพันธ์ใกล้ชิดกัน

จุดหนึ่งของ RAII คือเพื่อให้มั่นใจในความปลอดภัยยกเว้น - แอปพลิเคชันยังคงสอดคล้องกันในตัวเองเมื่อมีการโยนข้อยกเว้น ตั้งแต่แรกเห็นสิ่งนี้ไม่สำคัญ - เมื่อข้อยกเว้นทำให้เกิดขอบเขตออกตัวแปรท้องถิ่นในขอบเขตนั้นจำเป็นต้องถูกทำลาย

แต่จะเกิดอะไรขึ้นถ้าการโยนข้อยกเว้นเกิดขึ้นภายในตัวสร้าง

วัตถุไม่ได้ถูกสร้างอย่างสมบูรณ์ดังนั้นจึงไม่สามารถถูกทำลายได้อย่างปลอดภัย ตัวสร้างควรมีบล็อกลองตามที่จำเป็นเพื่อให้แน่ใจว่ามีการล้างข้อมูลที่จำเป็นใด ๆ เสร็จสิ้นก่อนที่จะทำการยกเว้น เมื่อข้อยกเว้นแพร่กระจายออกไปนอกขอบเขตที่วัตถุถูกสร้างขึ้นจะไม่มีการเรียก destructor เนื่องจากวัตถุไม่ได้ถูกสร้างขึ้นตั้งแต่แรก

พิจารณาเฉพาะสิ่งก่อสร้างสำหรับข้อมูลสมาชิกภายในวัตถุที่ถูกทำลาย หากหนึ่งในนั้นเกิดข้อยกเว้นรหัสคอนสตรัคเตอร์หลักของคุณจะไม่ทำงานเลย - แต่โค้ดบางตัวที่เป็นส่วนหนึ่งโดยนัยของคอนสตรัคเตอร์นั้นจะมี สมาชิกที่สร้างสำเร็จจะถูกทำลายโดยอัตโนมัติ สมาชิกใด ๆ ที่ไม่ได้ถูกสร้างขึ้น (รวมถึงสมาชิกที่โยนข้อยกเว้น) ไม่ได้

ดังนั้นโดยทั่วไป RAII เป็นนโยบายที่รับรองว่าสิ่งใดก็ตามที่ได้รับการก่อสร้างอย่างสมบูรณ์จะถูกทำลายในเวลาที่เหมาะสมโดยเฉพาะอย่างยิ่งเมื่อมีข้อยกเว้นเกิดขึ้นและวัตถุใด ๆ ก็ตามที่ถูกสร้างขึ้นอย่างสมบูรณ์ วัตถุที่สร้างขึ้นซึ่งคุณไม่สามารถรู้วิธีทำความสะอาดได้อย่างปลอดภัย) ทรัพยากรที่ปันส่วนยังเป็นอิสระ และงานจำนวนมากเป็นแบบอัตโนมัติดังนั้นโปรแกรมเมอร์จึงไม่ต้องกังวลกับเรื่องนี้มากนัก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.