抽象基类和纯虚函数

时间:2022-09-14 21:54:32

上一节介绍了虚函数是如何来实现多态的。但现实中,有时候我们创建基类的目的可能只是为了实现up-casting的目的,并不会真正去创建一个基类的对象。在这个时候,抽象基类就产生了。

抽象基类

怎样就可以叫抽象基类?它和别的基类的区别在哪?

所谓的抽象基类就是包含至少一个纯虚函数的类。抽象基类只实现了接口的作用。无法创建抽象基类的对象。

那么纯虚函数是啥?它和虚函数有啥区别?

所谓的纯虚函数就是加上关键字virtual并在函数的末尾加上=0.形式如下:

virtual returnValue functionName (parameters)=0;
例如,virtual void func(int) = 0;

纯虚函数和虚函数的区别在于纯虚函数在vtable中只是占位的作用,这个位置并不存放地址。纯虚函数的好处在于使得vtable变得不完全,从而可以方便的检查某个类是否是abstract class.

这样就提醒我们,如果一个函数是以一个抽象基类作为参数的话,这个参数只能是引用或指针。因为抽象基类不能创建对象。

虽然是抽象基类,但是它并不影响我们对于代码重用的功能。

抽象基类的好处在于防止了对象切片。什么事对象的切片呢?

对象切片(object slice)指的是upcast一个对象到另一个对象,而非指针或引用的upcast.
当将一个对象转换为其基类的时候,会调用基类的复制构造函数。而我们知道,vptr是在对象创建的过程中加入的。(下一讲会详细讲解构造函数中vptr的初始化)如果是基类的复制构造函数,那么自然加入的是基类的vptr,因此就无法实现多态了。