虚拟函数(C++)

来自RAD Studio
跳转到:航行搜索

转到虚拟功能索引

事实上的函数允许派生类提供基类函数的不同版本。您可以使用事实上的用于声明的关键字事实上的基类中的函数。通过以通常的方式声明函数原型,然后在声明前加上事实上的关键字。要声明纯函数(自动声明抽象类),请在原型前面加上事实上的关键字,并将函数设置为零。

虚拟int函数1(void);//虚函数声明。虚拟int函数2(void)=0;//纯函数声明。

函数声明不能同时提供纯说明符和定义。

例子:

结构C{虚拟void f(){}=0;//成形不良};

提供正文的唯一合法语法是:

结构TheClass{虚虚函数3(虚)=0;};虚拟void TheClass::funct3(void){//这里有一些代码。};

注:有关纯虚拟函数的讨论,请参见抽象类AbstractClasses。

当你申报时事实上的功能,请记住以下准则:

  • 它们只能是成员函数。
  • 可以将其声明为朋友属于另一类。
  • 它们不能是静态成员。

一个事实上的函数不需要在派生类中重新定义。您可以在基类中提供一个定义,以便所有调用都可以访问基函数。

要重新定义事实上的函数中,基类声明和派生类声明中的参数数量和类型必须相同。(重新定义的情况事实上的下面将讨论返回类型不同的函数。)一个重新定义的函数被称为覆盖基类函数。

您还可以声明函数intBase::Fun(int)和intDerived::Fun。在这种情况下,intDerived::Fun(int)可以隐藏任何基类中存在的任何其他版本的Fun(nt)。此外,如果类Derived定义了Fun()的其他版本(即具有不同签名的Fun(。

虚拟函数返回类型

通常,在重新定义事实上的函数,不能只更改函数返回类型。要重新定义事实上的函数中,新定义(在某些派生类中)必须与初始声明的返回类型和形式参数完全匹配。如果同名的两个函数具有不同的形式参数,C++会认为它们不同事实上的忽略了功能机制。

然而,对于基类中的某些虚函数,它们在派生类中的重写版本可以具有不同于重写函数的返回类型。只有在满足以下两个条件时,才能实现这一点:

  • 被覆盖的事实上的函数返回基类的指针或引用。
  • 重写函数返回派生类的指针或引用。

如果基类B和类D(从B公开派生)各自包含事实上的函数vf,则如果为d的对象d调用vf,那么所做的调用是d::vf(),即使访问是通过指向B的指针或引用进行的。例如,

结构X{};//基类。结构Y:X{};//派生类。结构B{虚拟void vf1();虚拟void vf2();虚拟void vf3();无效f();虚拟X*pf();//返回类型是指向基的指针。这个可以//被覆盖。};D类:公共B类{公众:虚拟void vf1();//虚拟说明符合法但多余。void vf2(int);//不是虚拟的,因为它使用的是不同的//参数列表。这将隐藏B::vf2()。//char vf3();//非法:只返回类型更改!无效f();Y*pf();//覆盖功能仅不同//返回类型中。返回指向的指针//派生类。};无效外部(){日期;//实例化DB*bp=&d;//从D*到B的标准转换*//使用函数表初始化bp//为对象d提供。如果没有//函数,使用函数//在B表中。bp->vf1();//调用D::vf1bp->vf2();//调用B::vf2,因为D的vf2具有不同的参数bp->f();//调用B::f(非虚拟)X*xptr=bp->pf();//调用D::pf()并转换结果//指向指向X的指针。D*dptr=&D;Y*密码=dptr->pf();//调用D::pf()并初始化密码器。//没有进行进一步的转换。}

D中的覆盖函数vf1自动事实上的. The事实上的说明符可以与派生类中的重写函数声明一起使用。如果其他类将从D派生,则事实上的关键字是必需的。如果没有从D派生出其他类,则使用事实上的是多余的。

a的解释事实上的函数调用取决于所调用对象的类型;对于非虚函数调用,解释只取决于指示其调用对象的指针或引用的类型。

事实上的函数为其多功能性定价:派生类中的每个对象都需要携带指向函数表的指针,以便在运行时选择正确的函数(后期绑定)。

另请参见