ใน C++ Exception Handling, กฎการจับ Exception ด้วย catch Block มีความเข้มงวดกว่าการ Type Conversion ปกติ: ไม่มี Implicit Conversion ระหว่าง Thrown Object และ Catch Parameter (ยกเว้นบางกรณีเฉพาะ)
กฎสำคัญ
- No Standard Conversions:
throw 'a'; catch(int)→ ไม่จับได้ (Char ไป Int ไม่ได้) - No User-Defined Conversions: Constructor Conversion, Conversion Operator ไม่ถูกใช้
- Derived → Base (Reference/Pointer): จับได้เฉพาะ Reference หรือ Pointer เท่านั้น (Polymorphism)
- Derived → Base (Value): เกิด Object Slicing (ตัดส่วน Derived ทิ้ง)
- catch(...): จับได้ทุกประเภท (Catch-all)
ตัวอย่าง 1: Char ไป Int ไม่ได้
try {
throw 'a'; // char
}
catch (int a) { // ไม่เข้ามา! ไม่มี char-to-int conversion ใน catch
cout << "Caught int";
}
catch (...) { // จับได้ที่นี่
cout << "Default catch";
}
// Output: Default catch
ตัวอย่าง 2: Conversion Constructor ไม่ถูกเรียก
class Base {};
class Derived {
public:
Derived(const Base&) { cout << "Conversion Ctor\n"; }
};
try {
Base b;
throw b; // Throw Base
}
catch (Derived d) { // ไม่เข้ามา! Conversion Constructor ไม่ถูกใช้
cout << "Caught Derived";
}
catch (...) {
cout << "Default catch";
}
// Output: Default catch
ตัวอย่าง 3: Polymorphic Catch (Reference) - ทำงานได้
class Base { virtual void foo() {} };
class Derived : public Base {};
try {
Derived d;
throw d;
}
catch (Base& b) { // จับได้! Reference Binding (No Slicing)
cout << "Caught Base&";
}
// Output: Caught Base&
ลำดับความสำคัญของ Catch Blocks
Catch Blocks ถูกตรวจสอบ ตามลำดับที่เขียน ต้องวาง Derived Class ก่อน Base Class:
try { ... }
catch (Derived& d) { ... } // ต้องอยู่ก่อน
catch (Base& b) { ... } // Base มาต่อท้าย
catch (...) { ... } // Catch-all ต้องท้ายสุด
Best Practices
- Throw โดย Value, Catch โดย Const Reference:
catch (const std::exception& e) - สร้าง Exception Hierarchy จาก
std::exception - หลีกเลี่ยง Throw Primitive Types (int, char) ใช้ Class แทน
- ใช้
std::current_exception/std::rethrow_exceptionสำหรับ Exception Propagation
สรุป
C++ Exception Matching ใช้ Exact Match หรือ Reference Binding To Base เท่านั้น ไม่มี Implicit Conversion ทำให้ Type Safety สูง แต่ต้องออกแบบ Exception Hierarchy และ Catch Order ให้ถูกต้อง