An example tutorial of virtual function implementation in C + +

Source: Internet
Author: User

Objective

C + + is divided into compile-time polymorphic and Run-time polymorphism. Run-time polymorphism relies on virtual functions, and most people may have heard that virtual functions are implemented by virtual function tables + virtual function pointers, but are they really? Although the C + + specification has complex language details, the underlying implementation mechanism is left to the compiler manufacturer's imagination. (It is not possible that a particular processor circuit structure natively supports virtual functions, or that the processor is not a Vonneumann type at all, or that future manufacturers invent more efficient data structures than virtual function tables.) )

virtual function table

Encapsulation combines the data and operations of an instance, but the instance itself has only data, no functions, and functions of the same class are shared. We'll prove it indirectly by an example.

1

2

3

4

5

6

7

8

9

ClassBase1

{

Public

Inta

Voidfunc () {cout << "heel" << Endl;}

};

BASE1 B1;

cout <<sizeof (B1) << Endl;

Print

1

4

If a virtual function is in the class, a virtual function pointer is added to the object, which points to a virtual function table that is the address of each virtual function.

1

2

3

4

5

6

+--------+    +---------+

| pvtbl |------>| vfunc1 |

+--------+    +---------+

|    Data1 | | Vfunc2 |

+--------+    +---------+

|    ...  | | ...   |

When a subclass inherits the parent class, it overwrites each item in the virtual function table in turn, and the item is retained if the subclass does not override an item. When an object is instantiated, the virtual function pointer exists as a hidden data in the instance. If normal member functions are invoked through the parent class pointer, because normal functions and types are bound together, the parent class member function is still invoked, and if a virtual function is invoked through the parent class pointer, the virtual function table (the virtual function table of subclasses) is found by the object's virtual pointer, and the virtual function item is positioned to achieve polymorphism.

The principle is not very simple? C + + is to implement advanced abstractions in this seemingly primitive way. This is the common practice of the compiler, as the Visual Studio 2013 compiler in my hand does, in order to improve performance, VS guarantees that virtual function pointers exist at the top of the object instance (and historically compilers do not do this, as if they were Borland?). )。

Implementation in Visual Studio 2013

Here's an example (this is because I know the memory layout of Visual Studio 2013 compiled objects)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

#include

USINGNAMESPACESTD;

Classbase

{

Public

Typedefvoid (*func) ();

Virtualvoidfunc1 () {cout << "base::func1" << Endl;}

Virtualvoidfunc2 () {cout << "base::func2" << Endl;}

Virtualvoidfunc3 () {cout << "base::func3" << Endl;}

};

Classderived:publicbase

{

Public

Virtualvoidfunc1 () {cout << "derived::func1" << Endl;}

Virtualvoidfunc3 () {cout << "derived::func3" << Endl;}

};

Intmain ()

{

Base B, B1;

int** pvirtualtable1 = (int**) &b;

cout << "Base object VTBL Address:" << pvirtualtable1[0] << Endl;

int** Pvirtualtable11 = (int**) &b1;

cout << "Another Base object VTBL address:" << pvirtualtable11[0] << Endl;

cout << "function in virtual table" << Endl;

for (inti = 0; (Base::func) pvirtualtable1[0][i]!= NULL; ++i)

{

Auto P = (base::func) pvirtualtable1[0][i];

P ();

}

cout << Endl;

Derived D;

int** pvirtualtable2 = (int**) &d;

cout << "Derived object VTBL Address:" << pvirtualtable2[0] << Endl;

cout << "function in virtual table" << Endl;

for (inti = 0; (Base::func) pvirtualtable2[0][i]!= NULL; ++i)

{

Auto P = (base::func) pvirtualtable2[0][i];

P ();

}

cout << Endl;

}

Print

1

2

3

4

5

6

7

8

9

10

11

12

Base Object Pvtbl address:0029da58

Another Base object Pvtbl address:0029da58

function Address invirtualtable

Base::func1

Base::func2

Base::func3

Derived Object Pvtbl Address:0029db20

function Address invirtualtable

Derived::func1

Base::func2

Derived::func3

As you can see, the virtual function tables for different instances of the same type are the same, and after inheriting, the subclasses have their own virtual function table, and the table has the corresponding update (DERIVED::FUNC1, derived::func3), and the items that are not overridden in the table remain the original value (BASE::FUNC2).

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.