การกำหนด = 0 หลัง declaration ของ virtual function เป็น **เพียงแค่ syntax** (ไวยากรณ์) เพื่อบอก compiler ว่าฟังก์ชันนี้เป็น **pure virtual function** ไม่มีความหมายทางคณิตศาสตร์หรือการกำหนดค่าใดๆ
Syntax
class Base {
public:
virtual void foo() = 0; // Pure virtual function
// ^^^^^^^^^^^^ แค่เครื่องหมาย ไม่ได้ "assign" ค่า 0
};
คุณสมบัติของ Pure Virtual Function
- **ไม่มี implementation** ใน base class (แต่สามารถมีได้ - เรียกได้ผ่าน qualified call)
- **Derived class ต้อง override** มิฉะนั้น derived class ก็จะเป็น abstract
- **Class ที่มี pure virtual function อย่างน้อย 1 ตัว = Abstract Class**
- **ไม่สามารถสร้าง object ของ abstract class ได้** (แต่ pointer/reference ได้)
ตัวอย่างโค้ด
#include <iostream>
using namespace std;
class Shape {
public:
// Pure virtual functions - interface
virtual double area() const = 0;
virtual double perimeter() const = 0;
// Virtual destructor สำคัญ!
virtual ~Shape() = default;
// สามารถมี regular virtual function ได้
virtual void printInfo() const {
cout << "Area: " << area() << ", Perimeter: " << perimeter() << endl;
}
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
double perimeter() const override {
return 2 * 3.14159 * radius;
}
};
class Rectangle : public Shape {
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override {
return width * height;
}
double perimeter() const override {
return 2 * (width + height);
}
};
int main() {
// Shape s; // ❌ Error: cannot instantiate abstract class
Circle c(5);
Rectangle r(4, 6);
Shape* shapes[] = {&c, &r};
for (Shape* s : shapes) {
s->printInfo(); // Polymorphic call
}
return 0;
}
ผลลัพธ์
Area: 78.5397, Perimeter: 31.4159 Area: 24, Perimeter: 20
ทำไมเลือกเลข 0?
- Historical reason: ใน C++ แรกๆ (CFront) ใช้ syntax นี้เพื่อแยกจาก regular virtual function
- No confusion: 0 เป็น literal ที่ไม่มี side effects ไม่สามารถเป็น function pointer ได้
- Consistency: คล้ายกับ NULL pointer concept (pointer to nothing)
- Simplicity: ไม่ต้องเพิ่ม keyword ใหม่ (เช่น
pureหรือabstract)
Pure Virtual Function ที่มี Body (Advanced)
Pure virtual function **สามารถมี definition ได้** (แต่ยังคงเป็น pure virtual):
class Base {
public:
virtual void cleanup() = 0; // Pure virtual
};
// Definition แยกต่างหาก (ยังคงเป็น pure virtual)
void Base::cleanup() {
cout << "Base cleanup logic" << endl;
}
class Derived : public Base {
public:
void cleanup() override {
Base::cleanup(); // เรียก base implementation ได้!
cout << "Derived cleanup" << endl;
}
};
สรุป
= 0 เป็น **syntax sugar** เพื่อบ่งบอกว่า "ฟังก์ชันนี้ไม่มี implementation ในคลาสนี้ และคลาสลูกต้อง implement เอง" มันไม่ได้หมายถึงการกำหนดค่า 0 ให้ฟังก์ชันหรือ pointer ใดๆ