虚拟和纯虚拟功能之间的区别
内容
虚函数和纯虚函数都是运行时多态的概念。 ‘之间的主要区别虚拟功能’ 和 “纯虚拟功能” 是“虚拟功能”在基类中有其定义,并且继承的派生类也对其进行了重新定义。纯虚函数在基类中没有定义,并且所有继承的派生类都必须重新定义它。
但是,由于在运行时根据所使用对象的类型指定了所调用的函数,因此虚拟函数也称为动态调度和运行时调度。
C ++和Java语言都支持多态。在Java中,术语“覆盖”代替“虚拟函数”,因为虚拟函数是C ++的术语。
- 比较表
- 定义
- 关键差异
- 结论
比较表
比较基础 | 虚拟功能 | 纯虚函数 |
---|---|---|
基本的 | 虚函数在基类中有其定义。 | Pure Virtual Function在基类中没有定义。 |
宣言 | 虚拟功能名称(parameter_list){。 。 。 。 }; | 虚拟功能名称(parameter_list)= 0; |
派生类 | 所有派生类都可以覆盖也可以不覆盖基类的虚函数。 | 所有派生类都必须重写基类的虚函数。 |
影响 | 虚拟功能本质上是分层的。如果任何派生类未覆盖基类的虚函数,则不会影响编译。 | 如果所有派生类都无法覆盖基类的虚函数,则将发生编译错误。 |
抽象类 | 没有概念 | 如果一个类至少包含一个纯虚函数,则将其声明为抽象。 |
虚函数的定义
的 虚拟功能 是基类的成员函数,并且由继承基类的派生类重新定义。不必所有继承的派生类都必须重新定义虚拟函数,它只能由可能需要其功能的那些派生类重新定义。通过在基类中声明带有关键字的函数来创建虚函数 '虚拟'.
宣言 :
class base {public:虚拟类型funt_name(parameter-list){。 。 。 };
继承的派生类可以重新定义虚拟函数,而无需任何“虚拟”关键字。派生类重新定义虚拟函数以完成其任务。由于虚拟函数是在派生类中重新定义的,因此同一函数有多种形式。现在,要调用哪个版本的函数,取决于要调用该函数的对象类型。
多级继承
在多级继承中,如果派生类已从其基类继承了虚函数,则当其本身用作另一个派生类的基类时,仍然可以覆盖该虚函数。因此,当虚拟函数被继承时,其虚拟性质也被继承。
虚拟函数本质上也是分层的,即,如果派生类未覆盖/重新定义从基类继承的虚拟函数,并且当派生类的对象调用该虚函数时,则将调用由基类定义的虚函数。
纯虚函数的定义
如上所示,如果派生类未覆盖虚函数,则使用由基类定义的虚函数。但是,如果基类本身未定义虚拟函数该怎么办。很多时候,基类没有为虚函数定义,或者有时您希望所有派生类都必须覆盖虚函数。
为了处理以上两种情况,C ++支持“纯虚函数”。在基类中声明了“纯虚函数”,但在基类中没有其定义。纯虚函数声明如下。
虚拟类型funct_name(parameter_list)= 0;
每当将基类中的虚函数设为“纯”时,每个派生类都必须强制重写基类的纯虚函数。如果派生类无法覆盖基类的纯虚函数,则将导致编译错误。
抽象类
至少包含一个纯函数的类称为“抽象类”。不能创建抽象类的对象,但是您可以创建对抽象类的引用和指针。可以通过继承抽象基类的派生类的对象访问抽象类的成员。
要声明抽象的类,请使用关键字 '抽象' 在......面前 '类' 关键词。
//例如抽象类class-name {。 。虚拟类型funct_name(parameter_list)= 0; 。 。 };
- 虚函数肯定在基类中定义,并在派生类中重新定义(覆盖)。另一方面,纯虚函数基类在基类中特别没有定义
- 如果需要,派生类重新定义(覆盖)虚函数,而在使用纯虚函数的情况下,派生类必须重新定义纯虚函数。
- 如果派生类无法重新定义(覆盖)虚函数,则可以使用基类的虚函数。相反,如果派生类无法覆盖纯虚函数,则会发生编译错误。
- 可以实例化包含虚拟函数的基类,即可以创建其对象。相反,包含纯虚函数的基类,即抽象类不能被实例化,因为抽象类未完全定义。
注意:
在整个程序中,“虚拟功能”和“纯虚拟功能”的原型保持不变。
结论:
“虚函数”和“纯虚函数”都有其重要性,就像在“虚函数”中一样,所有派生类都不需要重新定义虚函数,而我们希望所有派生类都应该重新定义虚函数,即纯虚此功能最适用于此。