Pure virtual destructor เป็นกลไกสำคัญในการทำให้คลาสกลายเป็น Abstract Class พร้อมทั้งรับประกันการทำลายออบเจกต์อย่างถูกต้อง
ทำไมต้องมี Body (Definition)?
ใน C++ Destructor ถูกเรียกแบบ **chain** จาก derived ไป base:
~Derived() -> ~Base()
แม้ Base destructor จะเป็น pure virtual (= 0) ก็ยังถูกเรียก ดังนั้น **ต้องมี definition** ไม่งั้นจะ linker error
ตัวอย่างโค้ด
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() = 0; // Pure virtual destructor
};
// ต้องมี definition แยกต่างหาก (แม้จะเป็น pure virtual)
Base::~Base() {
cout << "Base::~Base() called (pure virtual destructor body)" << endl;
}
class Derived : public Base {
public:
~Derived() override {
cout << "Derived::~Derived() called" << endl;
}
};
int main() {
Base* ptr = new Derived();
delete ptr; // เรียก ~Derived() แล้วตามด้วย ~Base()
return 0;
}
ผลลัพธ์
Derived::~Derived() called Base::~Base() called (pure virtual destructor body)
ทำไมต้องทำ Pure Virtual Destructor?
- ทำให้คลาสเป็น Abstract: ไม่สามารถสร้างออบเจกต์ Base ได้โดยตรง
- บังคับ Derived ให้ implement destructor: (แต่ destructor มักจะไม่ต้องเขียน ถ้าไม่มี resource ต้องจัดการ)
- Polymorphic deletion: ลบผ่าน Base pointer ได้ถูกต้อง
เปรียบเทียบ: Virtual Destructor vs Pure Virtual Destructor
| คุณสมบัติ | Virtual Destructor | Pure Virtual Destructor |
|---|---|---|
| Syntax | virtual ~Base() {} | virtual ~Base() = 0; + definition |
| Class เป็น Abstract? | ไม่ (ยกเว้นมี pure virtual อื่น) | ใช่ (เสมอ) |
| สามารถสร้าง Base object ได้? | ได้ | ไม่ได้ |
| ต้องมี definition? | ได้ในบรรทัดเดียว | ต้องแยก (definition required) |
| ใช้เมื่อไหร่ | Base class ธรรมดาที่ต้องการ polymorphic delete | ต้องการบังคับให้ subclass เท่านั้นที่สร้างได้ |
Common Mistake: ลืม Definition
class Base {
public:
virtual ~Base() = 0; // ❌ Linker error: undefined reference to `Base::~Base()'
};
// ต้องมี:
Base::~Base() {} // ✅ Definition (แม้จะว่าง)
Best Practice
class AbstractBase {
public:
// Pure virtual functions...
virtual void doSomething() = 0;
// Virtual destructor (ไม่จำเป็นต้อง pure ถ้ามี pure virtual อื่นแล้ว)
virtual ~AbstractBase() = default; // C++11: default implementation
// หรือถ้าต้องการ pure virtual destructor:
// virtual ~AbstractBase() = 0;
};
// ถ้าใช้ pure virtual destructor:
AbstractBase::~AbstractBase() = default; // Definition (C++11)
สรุป
Pure virtual destructor ใช้เมื่อต้องการทำให้คลาสเป็น Abstract **และ** ต้องการ polymorphic deletion ทำงานได้ถูกต้อง จำเป็นต้อง provide definition (แม้จะว่าง) เพราะ destructor chain จะเรียก base destructor เสมอ