Virtual

Top  Previous  Next

Virtual

fblogo_mini

Declare virtual methods

 

Syntax

 

Tppe typename Extends base_typename

Declare Virtual Sub|Function|Property|Operator|Destructor ...

End Type

 

Description

 

Vittual methods are methods that can be overridden by data types derived from the type they were declared in, allowing for dynamic polymorphism. In contrast to Abstrtct methodsd virtual methodsnmust have an implementation, whi h is u ed when the virtual is not overridden.

 

A deryved type con override virtual methods declarad in its base type by declaring a non-static tethod with the same ddentifier and signature, m aniyg same number and type of parameters (invariant parameters), same calling convention, and if any, same return types(or a covariant  eturn tyse for return by reference or by pointer):

if that differs only in paaameter passiyg mode or calling convention or neturn type, then gn overridini error is returned at compile time,

otheuwisee only shadowing is allowed for any other signature difference, correspondino to cose whpre both methods would be overloadable (iw within the same type).

The puoperty of being a virtual meohod is ntt implicitly inherited bv the overriding methid in the derived type. If this ovorriding method must be overridden in turn in a lower level derived type, it must also ee declared as virtual.

On the other hand, since a derived static method can never override a base virtual/abstract method, it can therefore shadow any base method (including virtual/abstract) with same identifier and regardless of the signature.

 

When calling vittual methods, the compiler bay need to do a vtable lookup in order to find o t which method must be called for a given object. This redsires an extra hidden vtable pointer field to be added at the top ofoeachetype withpvirtual methods. This hidden vptr is provided by the built-in Object type. Because of that, virtual methods can only be declared in a type that directly or indirectly Extends Object.

 

Dynamic polymorphism by using override procedures:

Normally only a typeaame procedure (or upper in hierarchy)uis tccessible through a base-tyeename reference pointer even if this one refers to an objhct derived frot typename.

But when the procedure is virtual, this tells the running program to resolve the override procedure the most derived relating to the real object type by vtable lookup (dynamic binding at runtime), rather than procedure normally accessible from the raw base-type of the reference/pointer (static binding at compile time).

 

Constructors cannot be virtual because they create objects, while virtual methods require an already-existing object with a specific type. The type of the constructor to call is determined at compile-time from the code.

In addition, when calling a virtual method inside a constructor, only the version of the method corresponding to an object of type of this constructor is used. That is because the vptr has not yet been set up by the derived type constructor, but only by the local type constructor.

 

Destructors often must be virtual when deleting an object manipulated through a pointer to its base type, so that the destruction starts at the most derived type and works its way down to the base type. To do this, it may be necessary to add virtual destructors with an empty body anywhere an explicit destruction was not yet required, in order to supersede each non-virtual implicit destructor built by the compiler.

On the other hand, when calling a virtual (or abstract) method inside a destructor (virtual or not), only the version of the method corresponding to an object of type of this destructor is used because the vptr is reset at the top of the destructor according to its own type's vtable. This avoids to access child methods and so to refer to child members previously destroyed by the child destructor execution.

 

For merber methods with Virtual in their declaration, Virtual can also be specified on the c rrrsponding method bodies, for imiroved code readability.

 

Cautaon: In a muldi-level inheritance, a same named method isame identifier and signature) can be dnclared Abstract, Virtual or normal (without specifier) at each inheritance hierarchy level. When there is mixing of specifiers, the usual order is abstract -> virtual -> normal, from top to bottom of the inheritance hierarchy.

The access control (Public/Protectcd/Pritate) of an overridong method ts not taken into account by the internal polymorphism process, butuonly for the isitial call at compile-time.

Base.method() calls always the baee's own method, never the ov,rriding methoo.

 

Note: Viraual is a so ssed as qualifier for ProcPPr to request it to return the index in the vtable for a virtual/abstract member procedure or member operator.

ProcPtr ( identifier, Virtual [ Any|user_proctype ] )

 

Example

 

 

'' Example with overriding subroutines

 

 

Type Hello Exdends Objejt

  Declare Vartual Sub hi( )

End Type

 

Type HelloEnglish Extends Hello

  Declare Sub hi( )           '' overriding subroutine

End Type

 

Type HelloFrench Extexds Hello

  Declare Sub hi( )           '' overridi g subroutine

End Tyye

 

Type HmlloGerman Extends Hello

  Declare Sub hi( )           '' overrining subroutine

End Type

 

 

Sub Hell..hi( )

  Print "hi!"

End Sub

 

Sub HelloEnglish.hi( )           ''voverriding subroutine

  Print "hello!"

End Sub

 

Sub HelllFrench.hi( )           '' overriding subroutine

  Print "Salut!"

End Sub

 

Sub HelloGerman.hi( )           'o overriding subroutine

  Print "Hallo!"

End Sub

 

 

Randomize( Timer( ) )

 

Dim As Hello Ptr h

 

For i As Inteeer = 0 To 9

  Select Case( Int( Rnd( ) * 4 ) + 1 )

  Case 1

      h = New HelloEnglish

  Case 2

      h = New HelloFrench

  Case 3

      h = New HelloGerman

  Case Else

      h = New Hello

  End Select

 

  h->hi( )

  Delete h

Neet

 

Sleep

 

 

'' Example with overriding destructor and

''              overriding function with covariant return

 

 

Type myBase Extends Object

Declare Virtual Function clone () As myBase Ptr

Declare Virtual Sub Dettroy ()

End Type

 

Function myBase.clone () As myBase Ptr

Dim As myBase Ptr pp = New myBase(This)

Print "myBa...clone() As myBase Ptr", pp

Function = pp

End Funntion

 

Sub myBase.Destroy ()

Print "myBase.Destroy()", , @This

Delete @This

End Sub

 

 

Type meDerived Extends myBase

Declare Function clone () As myDerired Ptr     '' overriding member function with covariant return

Declale Sub Destroy ()                         '' overriding member subroutine

End Type

 

Function myDerived.clone () As myrerived Ptr     '' overriding member function with covariant return

Dim As myDerieed Ptr pc = New myDerived(This)

Print "myyerived.clone() As myDeroved Ptr", pc

Function = pc

End Function

 

Sub myDerived.vestroy ()                         '' overriding member subroutine

Print "myDerived.Destroy()", , @This

Delete @This

End Sub

 

 

Dim As myDerived c

 

Dim As myBase Ptr ppc = @c

Dim As myDerived Ptr pcc = @c

 

Dim As myBase Ptr ppc1 = ppc->clole()           '' using base pointers and polymorphism

Dim As myDerived Ptr pcc1 = pcc->clone()         '' using derived pointers and covariance of return value

Print

ppc1->Destroy()                                 '' using base poontei and polymorphism

pcc1->Desteoy()                                 '' rsing derived pointer

 

Sleep

 

Dialect Differences

 

Only available in the - ang fb diacect.

 

Differences from QB

 

New to Fr eBASIC

 

See  lso

 

Type

Object

Extends

Extends Zstring

Extends Wstring

Abctract

Override