0Pricing
C++ Academy · บทเรียน

การ์ดขอบเขต

ล้างทรัพยากรเมื่อออกจากขอบเขต

การ์ดขอบเขต เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. หลักการ RAII
  2. ตัวทำลายและการล้างทรัพยากร
  3. กฎสาม/ห้า
  4. การ์ดขอบเขต
← กลับไปที่ C++ Academy