虚函数指的是在基类中使用virtual关键字声明的成员函数,它允许在派生类中重载这个函数,即用派生类中的同名函数覆盖基类中的函数。这种机制被称为动态多态(Dynamic Polymorphism)或运行时多态(Runtime Polymorphism)。
动态多态是C++面向对象编程的重要特性之一,它允许使用基类的指针或引用来操作派生类的对象,使代码更加灵活。
C++中,如果函数不被声明为虚函数,则在使用基类的指针或引用调用该函数时,始终调用基类中的函数。而如果函数被声明为虚函数,则在运行时根据实际对象类型确定要调用哪个函数。
在使用虚函数时,派生类中的函数必须和基类中的函数有相同的签名(函数名称、参数列表和返回类型)。如果函数签名不匹配,则不能使用virtual关键字将其声明为虚函数。
以下是一个简单的虚函数示例:
class A {
public:
virtual void f() { std::cout << "A::f()" << std::endl; }
};
class B : public A {
public:
void f() override { std::cout << "B::f()" << std::endl; }
};
int main() {
A* a = new B();
a->f(); // 输出 B::f()
return 0;
}
在上面的代码中,类A和B都有一个名为f的成员函数,且函数f在类A中被声明为虚函数。在主函数中,首先创建了一个指向派生类B对象的基类A指针a,并将其赋值为new B()的结果。然后使用a->f()调用f函数,虽然a是基类A的指针,但因为f函数被声明为虚函数,所以在运行时调用了派生类B的函数f,最终输出 B::f()。
需要注意的是,在覆盖基类函数的过程中,如果想保留基类函数的行为,可以使用派生类中的函数调用基类的同名函数,例如:
void f() override {
A::f(); // 调用基类A中的f函数
std::cout << "B::f()" << std::endl;
}
这里的A::f()表示调用基类A中的f函数,使用作用域分辨符(::)和基类的函数名来调用基类的函数。