A common expectation is that a pointer to a derived class object should access derived class members. How ever, a base pointer pointing to a derived object may access derived member varaibles but not member funcsions, leading to inconsistent behavior. For example, a Teacher object might incorrectly display as unemployed.
Virtual functions resolve this. By declaring a function with the virtual keyword in the base class, a base pointer can invoke the derived class's overridden function:
class Person {
public:
virtual void displayRole() {
cout << "Role: Unspecified" << endl;
}
};
class Teacher : public Person {
public:
void displayRole() override {
cout << "Role: Teacher" << endl;
}
};
int main() {
Person* personPtr = new Teacher();
personPtr->displayRole(); // Outputs: Role: Teacher
delete personPtr;
return 0;
}
This behavior is polymorphism: the same pointer call (personPtr->displayRole()) executes different implementations based on the object's actual type. Polymorphism allows a base pointer to access derived class members comprehensively, particularly member functions.
Without virtual, member function calls depend on the pointer's declared type. With virtual, calls depend on the object's runtime type, enabling dynamic dispatch.