Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

เกิดอะไรขึ้นเมื่อ Virtual Function ถูกเรียกภายใน Non-Virtual Function ใน C++?


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 ยากพยากรณ์