Accesses the virtual method of the ancestor class (direct access to the ancestor class's vmt, but this method may not be reliable in the new version)

Source: Internet
Author: User

Accessing virtual methods of ancestor classesquestions raised

in a virtual method covered by subclasses, the implementation of the parent class can be called with inherited , but sometimes we do not need the implementation of the parent class, but rather we want to jump over the parent class's method of calling the ancestor class directly.

For example, suppose there are three classes that are implemented as follows:

Type

Tclassa = Class

Procedure Proc; Virtual

End

TCLASSB = Class (Tclassa)

Procedure Proc; Override

End

TCLASSC = Class (TCLASSB)

Procedure Proc; Override

End

Implementation

Procedure Tclassa.proc;

Begin

ShowMessage (' Proc of Class A ');

End

Procedure Tclassb.proc;

Begin

ShowMessage (' Proc of Class B ');

End

Procedure Tclassc.proc;

Begin

ShowMessage (' Proc of Class C ');

End

Call the virtual method Procwith the following code:

Var

C:tclassa;

Begin

C: = tclassc.create;

C.proc;

C.free;

End

We know that the final call is Tclassc.proc; If you add inheritedto the tclassc.proc , tclassb.proc can get the call But now, what if you want to call Tclassa.procdirectly in tclassc.proc ?

the way to solve

If it is C + +, just write this:tclassc::P Roc.

In Delphi But there is no way to do,Delphi does not allow us to jump-level call ancestor class method. Nonetheless, it is possible to find a solution from another perspective.

The solution is VMT, each class is a pointer to VMT , and VMT is actually used to save the virtual method. In the affirmative of the VMT , all the virtual methods from the ancestor class are listed, only the VMT of the Tclassa is shifted to Proc, and then the call can be called.

Let's see how this problem can be solved:

Procedure Tclassc.proc;

Type

Tproc = procedure of object;

Var

M:tmethod;

Begin

M.code: = Ppointer (Tclassa) ^;

M.data: = self;

Tproc (M) ();

ShowMessage (' Proc of Class C ');

End

Once the call is executed, you can see that it pops up first:Proc of Class A; then pops up:Proc of Class C. This indicates that Tclassa.proc was called in the Tclassc.proc .

tclassa Span style= "font-family: ' Times New Roman ';" >VMT 0 offset is proc addresses, and inherits from tobject , tobject itself has some virtual methods, such as afterconstruction , so where are these stored?

The secret is on the negative offset of the VMT , which declares the structure offset of the virtual table in the System unit and has the afterconstruction entry point in the negative direction. It should be noted that several of the positive orientations of the structure offsets are declared in theSystem unit, and the 0 offset (vmtqueryinterface) is not a storage QueryInterface, instead, the first virtual method (except tobject ) is stored.

Here is the VMT layout from the Help:

Offset Type Description

-76 Pointer Pointer to virtual method table (or nil)

-72 Pointer Pointer to Interface table (or nil)

-68 Pointer Pointer to Automation information table (or nil)

-64 Pointer Pointer to instance initialization table (or nil)

-60 Pointer Pointer to type information table (or nil)

-56 Pointer Pointer to field definition table (or nil)

-52 Pointer Pointer to Method definition table (or nil)

-48 Pointer Pointer to dynamic Method table (or nil)

-44 Pointer Pointer to short string containing class name

-40 Cardinal instance size in bytes

-36 Pointer Pointer to a Pointer to ancestor class (or nil)

-32 Pointer Pointer to entry point of Safecallexception method (or nil)

-28 Pointer entry point of Afterconstruction method

-24 Pointer entry point of Beforedestruction method

-20 Pointer entry point of Dispatch method

-16 Pointer entry point of DefaultHandler method

-12 Pointer entry point of Newinstance method

-8 Pointer entry point of Freeinstance method

-4 Pointer entry point of Destroy destructor

0 Pointer entry point of first user-defined virtual method

4 Pointer entry point of second user-defined virtual method

PostScript

It is not safe to call virtual methods with virtual tables, since Borland (codegear) does not assure you that each Delphi version of the VMT layout is the same.

Therefore, the use of this method should be cautious.

http://blog.csdn.net/linzhengqun/article/details/1755493

Accesses the virtual method of the ancestor class (direct access to the ancestor class's vmt, but this method may not be reliable in the new version)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.