การ์ดขอบเขต
ล้างทรัพยากรเมื่อออกจากขอบเขต
การ์ดขอบเขต เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวป้องกันขอบเขตคืออะไร
ตัวป้องกันขอบเขต คืออ็อบเจ็กต์ตามแนวคิด RAII ที่มีหน้าที่เพียงดำเนินการล้างทรัพยากรเมื่อออกจากขอบเขต แม้จะออกจากฟังก์ชันด้วยการคืนค่าก่อนกำหนดหรือข้อยกเว้นก็ตาม
ปัญหาที่ตัวป้องกันแก้ไข
หากไม่มีตัวป้องกัน การล้างทรัพยากรหลังคำสั่งคืนค่าก่อนกำหนดหรือคำสั่งโยนข้อยกเว้นอาจถูกลืมได้ง่าย ตัวป้องกันขอบเขตทำให้การดำเนินการนี้เกิดขึ้นโดยอัตโนมัติ
ตัวป้องกันการล็อก: ตัวป้องกันขอบเขตมาตรฐาน
std::lock_guard จะล็อกมิวเท็กซ์เมื่อสร้าง และปลดล็อกเมื่อทำลาย จึงเป็นตัวป้องกันขอบเขตสำหรับการล็อกที่มีมาให้ในมาตรฐาน
#include <mutex>
std::mutex m;
void critical() {
std::lock_guard<std::mutex> lk(m); // locked
// ... work ...
} // unlocked automaticallyตัวป้องกันที่เขียนขึ้นเอง
คุณสามารถเขียนตัวป้องกันที่เก็บฟังก์ชันไว้ แล้วเรียกใช้ฟังก์ชันนั้นในตัวทำลายได้
#include <iostream>
#include <functional>
class ScopeGuard {
std::function<void()> fn;
public:
ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
~ScopeGuard() { fn(); }
};
int main() {
ScopeGuard g([] { std::cout << "cleanup\n"; });
std::cout << "work\n";
}การล้างทรัพยากรทำงานเมื่อคืนค่าก่อนกำหนด
เนื่องจากตัวทำลายทำงานเมื่อออกจากขอบเขต การดำเนินการของตัวป้องกันจึงทำงานไม่ว่าฟังก์ชันจะสิ้นสุดลงด้วยวิธีใดก็ตาม
#include <iostream>
#include <functional>
class ScopeGuard {
std::function<void()> fn;
public:
ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
~ScopeGuard() { fn(); }
};
void run(bool stop) {
ScopeGuard g([] { std::cout << "always cleaned\n"; });
if (stop) return;
}
int main() { run(true); }การล้างทรัพยากรทำงานเมื่อเกิดข้อยกเว้น
หากการคลายสแตกของข้อยกเว้นผ่านขอบเขต ตัวทำลายของตัวป้องกันก็ยังทำงานและปล่อยทรัพยากรอย่างปลอดภัย
การยกเลิกตัวป้องกัน
บางครั้งคุณอาจต้องการข้ามการล้างทรัพยากร เนื่องจากการดำเนินการสำเร็จแล้ว ตัวป้องกันจริงจะมี dismiss() เพื่อปิดใช้งานการดำเนินการดังกล่าว
#include <iostream>
#include <functional>
class ScopeGuard {
std::function<void()> fn;
bool active = true;
public:
ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
void dismiss() { active = false; }
~ScopeGuard() { if (active) fn(); }
};
int main() {
ScopeGuard g([] { std::cout << "rollback\n"; });
g.dismiss(); // success: no rollback
}ใช้สำหรับการย้อนกลับ
ตัวป้องกันขอบเขตมีประโยชน์อย่างยิ่งกับโค้ดเชิงธุรกรรม: ลงทะเบียนการดำเนินการย้อนกลับ ทำงานที่ต้องทำ แล้วปิดใช้งานตัวป้องกันเมื่อสำเร็จ
ตัวป้องกันย้ายได้เท่านั้น
ไม่ควรคัดลอกตัวป้องกัน เพราะการคัดลอกจะทำให้การดำเนินการทำงานสองครั้ง ควรทำให้ตัวป้องกันย้ายได้เท่านั้นหรือคัดลอกไม่ได้
ตัวช่วยมาตรฐานและจากไลบรารี
std::scoped_lock ป้องกันมิวเท็กซ์หลายตัว และไลบรารีอย่าง GSL ก็มี finally ให้ใช้ โค้ดหลายโครงการมีเครื่องมือ ScopeGuard ขนาดเล็กเป็นของตนเอง
เลือกใช้ชนิดข้อมูลตามแนวคิด RAII ที่เฉพาะเจาะจง
เมื่อมีชนิดข้อมูลตามแนวคิด RAII ที่ออกแบบมาเฉพาะ เช่น ตัวป้องกันการล็อก ตัวชี้เฉพาะ หรือกระแสไฟล์ ให้เลือกใช้ชนิดนั้น ใช้ตัวป้องกันขอบเขตทั่วไปเฉพาะกับการล้างทรัพยากรเฉพาะกิจที่ไม่มีตัวห่อหุ้มตามธรรมชาติ
ตรวจสอบความเข้าใจสั้น ๆ
ทดสอบความเข้าใจของคุณเกี่ยวกับตัวป้องกันขอบเขต
สรุป
คุณได้เรียนรู้ว่าตัวป้องกันขอบเขตจะล้างทรัพยากรโดยอัตโนมัติเมื่อออกจากขอบเขตด้วยแนวคิด RAII โดยรองรับการคืนค่าก่อนกำหนดและข้อยกเว้น รองรับการย้อนกลับด้วย dismiss() และควรเป็นชนิดที่ย้ายได้เท่านั้น เมื่อมีชนิดข้อมูลตามแนวคิด RAII ที่เฉพาะเจาะจง ให้เลือกใช้ชนิดนั้น
คำถามที่พบบ่อย
บทเรียน “การ์ดขอบเขต” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การ์ดขอบเขต” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การ์ดขอบเขต”
ล้างทรัพยากรเมื่อออกจากขอบเขต คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การ์ดขอบเขต” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ