一、虚函数的基本概念
虚函数是C++中用于实现多态的机制之一,它能够让我们在基类中定义函数,而在派生类中进行重写,让程序在运行时根据对象所属的实际类型来调用相应的函数。
C++的虚函数的应用场景主要在于,我们定义一个基类,然后在派生类中重写相应的虚函数,可以使得程序能够更加灵活,根据具体的需求来调用不同的函数。比如,在一个动物类中定义虚函数eat()和sleep(),然后在派生类中定义不同类型的动物比如狗类和猫类,并分别实现eat()和sleep()函数,就可以根据实际需要来使用这些函数了。
虚函数的定义:在基类中的虚函数,可以在其后面添加关键字virtual,表示这是一个虚函数。
class Animal { public: virtual void eat(); virtual void sleep(); };
二、纯虚函数的定义
纯虚函数是一种没有实现的虚函数。在基类中定义一个纯虚函数,其语法与虚函数基本相同,但是在函数的后面加上了=0。
定义纯虚函数的主要目的是为了让派生类必须实现这个函数,为了达到这个目的,我们不能在声明的时候直接将纯虚函数赋值为0,只能在具体的派生类中实现这个函数。如果某个派生类没有实现这个纯虚函数,那么该派生类也会变成抽象类,无法实例化。
纯虚函数的定义:
class Animal { public: virtual void eat() = 0; virtual void sleep() = 0; };
三、虚函数与纯虚函数的区别
1. 虚函数与纯虚函数的定义方式不同
虚函数的定义在函数的声明中添加virtual关键字即可,而定义一个纯虚函数在函数声明后面加上=0
// 定义虚函数 virtual void eat(); // 定义纯虚函数 virtual void eat() = 0;
2. 纯虚函数是抽象类的标记
对于含有纯虚函数的类,称为抽象类。在抽象类中,由于没有实现纯虚函数,所以无法创建该抽象类的实例。
虚函数不需要被实现,可以被覆盖或不被覆盖。
class Animal { public: virtual void eat() = 0; // 纯虚函数 virtual void sleep(); // 虚函数 };
3. 实现方式不同
派生类中对于纯虚函数和虚函数的实现方式都是不一样的。纯虚函数必须在派生类中被实现,而虚函数可选择是否实现。否则,当该虚函数被调用时,将会执行基类的版本。
class Dog : public Animal { public: virtual void eat() { // 狗类的具体实现 } virtual void sleep() { // 狗类的具体实现 } };
4. 区别体现在内存布局上
虚函数会为每个包含虚函数的对象添加一个虚函数表指针,指向一个全局的虚函数表(Virtual Table),维护虚函数指针及其所指向的函数的关系。
而对于纯虚函数来说,虚函数表中没有其对应的函数地址,只是一个空指针,这也是纯虚函数无法被直接调用的原因。
四、总结
在实际应用中,虚函数和纯虚函数都有各自的优劣。虚函数能够提供默认实现,不完全由派生类重写,而纯虚函数则能够确保派生类实现了该函数,让程序更加稳定。我们应该根据具体需求来选择使用哪种方式。