ใน C++ access specifier ตรวจสอบที่ compile-time ตาม static type ของ pointer/reference ไม่ใช่ dynamic type ของ object จริง นี่ทำให้ derived class สามารถ override method ด้วย access specifier ที่เข้มงวดกว่า (เช่น private) ได้ และยังเรียกผ่าน base pointer ได้
กรณีที่ 1: เรียกผ่าน Derived Object โดยตรง → Error
class BaseClass {
public:
virtual void display() { cout << "Base"; }
};
class DerivedClass : public BaseClass {
private:
void display() { cout << "Derived"; } // private override
};
int main() {
DerivedClass d;
d.display(); // Error: private
}
Error
error: 'virtual void DerivedClass::display()' is private within this context
กรณีที่ 2: เรียกผ่าน Base Pointer → OK!
int main() {
BaseClass *b = new DerivedClass;
b->display(); // OK! เรียก Derived::display() แม้จะเป็น private
}
เอาต์พุท
Derived
เหตุผล
- Compile-time: ตรวจสอบ
b->display()→BaseClass::display()เป็น public → ผ่าน - Runtime: dynamic dispatch เรียก
DerivedClass::display()จริงๆ → ไม่ตรวจสอบ access specifier อีก
ข้อสรุปสำคัญ
- Access specifier ไม่ส่งผลต่อ virtual dispatch
- Override ด้วย private ได้ แต่เรียกได้เฉพาะผ่าน base pointer/reference
- เป็นการออกแบบที่อาจสับสน ควรหลีกเลี่ยงเว้นแต่มีเหตุผลเฉพาะเจาะจง