Polymorphism ทำงานได้แม้ virtual function จะถูกเรียกจากภายใน non-virtual function เพราะการ dispatch ขึ้นอยู่กับ vptr/vtable ของ object จริง ไม่ใช่ฟังก์ชันที่เรียก
ตัวอย่าง
#include <iostream>
using namespace std;
class BaseClass {
public:
void display() { cout << "Base display" << endl; }
void call_disp() {
cout << "Calling display() from base" << endl;
this -> display(); // เรียก virtual function
}
};
class DerivedClass : public BaseClass {
public:
void display() { cout << "Derived display" << endl; }
void call_disp() {
cout << "Calling display() from derived" << endl;
this -> display();
}
};
int main() {
BaseClass *bp = new DerivedClass;
bp->call_disp(); // เรียก non-virtual ของ Base
}
เอาต์พุท
Calling display() from base class Print function from the base class
แก้ไข: ตัวอย่างโค้ดต้นฉบับมี typo ให้ call_disp เป็น non-virtual ใน Base แต่ Derived มี call_disp แยก (hide) ทำให้เรียก Base version แต่ภายใน Base::call_disp เรียก this->display() ซึ่งเป็น virtual → เรียก Derived::display() ได้จริง
โครงสร้างภายใน (vtable & vptr)
- vtable: ตาราง function pointers ต่อ class เก็บ address ของ virtual functions
- vptr: pointer ในแต่ละ object ชี้ไป vtable ของ class จริง
เมื่อเรียก this->display() คอมไพเลอร์สร้างโค้ด: (*this->vptr[display_index])(this) → dispatch ตาม object จริง
สรุป
- Virtual function เรียกจากที่ไหนก็ตาม (แม้ non-virtual function) ก็ยัง dispatch ตาม dynamic type
- Non-virtual function ไม่มี vtable entry เรียกผ่าน static binding
- การ design: ระวัง non-virtual function ที่เรียก virtual function อาจทำให้ behavior ยากพยากรณ์