在C++的面向对象编程中,虚函数是一个十分重要的概念。虚函数的引入使得C++的继承和多态性得以完善,使程序的编写更具灵活性和可维护性。
虚函数的作用
虚函数的主要作用是实现运行时绑定,以实现多态性,即在基类中定义虚函数,在派生类中按照需求进行重定义,而在程序运行时,根据实际对象的类型选择调用哪个函数。这种方式通常将运行时动态绑定称为“延迟绑定”。
下面以一个简单的示例阐述虚函数的作用。首先有一个基类Person,其中有虚函数output:
```
class Person
{
public:
virtual void output()
{
cout<<"The person is a human."< } } ``` 接着有派生类Student,其中也定义了output函数: ``` class Student:public Person { public: virtual void output() { cout<<"The person is a student."< } } ``` 现在我们可以定义一个指向Person的指针,并依次指向一个Person和一个Student对象: ``` Person *p; Person personObj; Student studentObj; p=&personObj; p->output(); p=&studentObj; p->output(); ``` 如果没有虚函数的存在,我们期望p->output()能够分别输出"The person is a human."和"The person is a student."。但由于没有继承关系检查,编译器会默认在编译期间根据指针类型选择调用哪个output函数,即都会输出"The person is a human."。但使用虚函数后,输出结果会按照我们的预期,先输出"The person is a human.",再输出"The person is a student.",实现多态性调用不同的函数。 虚函数的使用 接下来,我们来看一下虚函数的使用。 虚函数在类成员函数前加上virtual关键字进行定义。虚函数可以被继承,即在派生类中保持原有的虚函数,并实现其他额外的虚函数,也可以对基类的虚函数进行重写,即在派生类重载基类的虚函数,并且不必保留原有的虚函数。 如果要指定不允许一个虚函数被重写,可以在成员函数前面加上关键字final。例如: ``` virtual void func() final; ``` 使用final修饰的虚函数不能被任何派生类进行重写。 另外,如果派生类使用基类中存在的虚函数,但不想进行重写,可以在派生类中定义函数,函数名与基类的虚函数相同,但不需要加virtual关键字,可称之为虚函数的“显式实现”。例如: ``` class Derived:public Base { public: void func() { Base::func(); } } ``` 虚函数还可以是纯虚函数,简称“纯虚函数”。纯虚函数只有函数接口,没有函数体。使用纯虚函数的作用是,当我们不知道如何在基类中实现虚函数时,可以把它定义为纯虚函数,将任务交给派生类来完成。 定义纯虚函数的方式是在虚函数定义的末尾加上=0,例如: ``` virtual void func()=0; ``` 当派生类从基类继承了纯虚函数而没有实现时,会被认为也是抽象类。如果在派生类中不实现继承的纯虚函数,也会被认为是抽象类,实例化时会报错。 总结 本文从虚函数的作用入手,详细介绍了虚函数的使用方法。虚函数是C++中非常重要的概念,它提供了多态性的实现方式,在实际工作中具有非常广泛的应用价值,掌握虚函数的用法可以让我们更好地编写高效、可扩展和易于维护的C++程序。