In-depth study of the C ++ Object Model

Source: Internet
Author: User
Tags scalar

Recently, in order to thoroughly understand the object model of C ++, how does the compiler implement polymorphism and what is the virtual table?CodeTo implement and deduce the object model of C ++.

First, define the following inheritance system: source code

 

Then construct the Object Pointer. The Code is as follows:

Int _ tmain (INT argc, _ tchar * argv [])

{

Ivtbl * pvtbl = NULL;

 

// VT to real1

Int isize = sizeof (vtblreal1 );

Pvtbl = new vtblreal1 ();

Void (_ thiscall vtblreal1: * PFn) (void) = & vtblreal1: F2; // assign values to the member function pointer Declaration

// Void * ptemp = (void *) (& vtblreal1: F2 );

If (pvtbl! = NULL)

{

Pvtbl-> F1 ();

Pvtbl-> F2 ();

(Vtblreal1 *) pvtbl-> * PFn) (); // call the member function pointer

Delete pvtbl;

}

 

// VT to realb

Pvtbl = new vtblrealb ();

If (pvtbl! = NULL)

{

Pvtbl-> F1 ();

Delete pvtbl;

}

 

// VT to Diamond

// Ivtbl * pvtbl = new vtbldiamond (); // The conversion is not clear about vtblreal1 or vtblrealb ??? Tangle

Vtblreal1 * pvtblreal1 = new vtbldiamond ();

If (pvtblreal1! = NULL)

{

Pvtblreal1-> F1 ();

 

Vtblrealb * ptempvtbb = dynamic_cast <vtblrealb *> (pvtblreal1 );

Ptempvtbb-> F1 ();

 

Delete pvtblreal1;

}

 

Vtblrealb * pvtbrealb = new vtbldiamond ();

If (pvtbrealb! = NULL)

{

Ivtbl * pvtbl = dynamic_cast <ivtbl *> (pvtbrealb );

Pvtbl-> F1 ();

Delete pvtbrealb;

}

Return 0;

}

The execution result is as follows:

 

Let's perform disassembly and debugging to see how the compiler helps us implement it?

Let's look at the initialization of an object from the Assembly perspective.

// Vtbldemo. cpp: defines console applicationsProgram.

//

 

# Include "stdafx. H"

# Include "ivtbl. H"

# Include "vtblbase. H"

# Include "vtblreal1.h"

# Include "vtblrealb. H"

# Include "vtbldiamond. H"

 

Int _ tmain (INT argc, _ tchar * argv [])

{

00961690 push EBP

00961691 mov EBP, ESP

00961693 push 0 ffffffffh

00961695 push offset _ ehhandler $ _ wmain (965468 H)

0096169a mov eax, dword ptr fs: [00000000 H]

009616a0 push eax

009616a1 sub ESP, 1dch // apply for stack space

009616a7 push EBX

009616a8 push ESI

009616a9 push EDI

009616aa Lea EDI, [ebp-1E8h]

009616b0 mov ECx, 77 H

009616b5 mov eax, 0 cccccccch

009616ba rep STOs dword ptr es: [EDI]

009616bc mov eax, dword ptr [___ security_cookie (96a0a8h)]

009616c1 XOR eax, EBP

009616c3 push eax

009616c4 Lea eax, [ebp-0Ch]

009616c7 mov dword ptr fs: [00000000 H], eax

Ivtbl * pvtbl = NULL;

009616cd mov dword ptr [ebp-14h], 0 // initialize pvtbl pointer to null

 

// VT to real1

Int isize = sizeof (vtblreal1 );

009616d4 mov dword ptr [ebp-20h], 0ch // assign sizeof (vtblreal1) to the ebp-20h, that is, the isize local variable)

//? Why = 0ch = (sizeof (vftable) + sizeof (DWORD m_dwvalue) + sizeof (m_baseval) = 12

Pvtbl = new vtblreal1 ();

009616db push 0ch // sizeof (vtblreal1)

009616dd call operator new (9611e0h) // internally call malloc to apply for heap Space

009616e2 add ESP, 4

009616e5 mov dword ptr [ebp-140h], eax // assign the applied memory address to the ebp-140h (pvtbl pointer)

009616eb mov dword ptr [ebp-4], 0

009616f2 cmp dword ptr [ebp-140h], 0 // compare whether it is null, if it is null, jump to 96170eh

009616f9 je wmain + 7eh (96170eh)

009616fb mov ECx, dword ptr [ebp-140h] // assign the applied memory address to ECx

00961701 call vtblreal1: vtblreal1 (961_ch) // call the vtblreal1 constructor ?? What do constructors do? See the following detailed descriptions of vtblreal1 constructor:

00961706 mov dword ptr [ebp-1E4h], eax // assign the return value to the ebp-1e4h ?? Ebp-140h to view the following object initialization Research

0096170c JMP wmain + 88 h (961718 H)

0096170e mov dword ptr [ebp-1E4h], 0

00961718 mov eax, dword ptr [ebp-1E4h]

0096171e mov dword ptr [ebp-14Ch], eax

00961724 mov dword ptr [ebp-4], 0 ffffffffh

0096172b mov ECx, dword ptr [ebp-14Ch]

00961731 mov dword ptr [ebp-14h], ECx

Void (_ thiscall vtblreal1: * PFn) (void) = & vtblreal1: F2; // assign values to the member function pointer Declaration

00961734 mov dword ptr [ebp-2Ch], offset vtblreal1: 'vcall' {4} '(9611feh) // vtblreal1: 'vcall' {4 }':

// 00da11fe JMP vtblreal1: 'vcall' {4} '(0da1c80h)

// 00da1c80 mov eax, dword ptr [ECx]

// 00da1c82 jmp dword ptr [eax + 4]

// Jump to ECx + 4 vtblreal1: F2 () Address

 

 

// Void * ptemp = (void *) (& vtblreal1: F2 );

If (pvtbl! = NULL)

0096173b cmp dword ptr [ebp-14h], 0

0096173f je wmain + 128 H (9617b8h)

{

Pvtbl-> F1 ();

00961741 mov eax, dword ptr [ebp-14h]

00961744 mov edX, dword ptr [eax]

00961746 mov ESI, ESP

00961748 mov ECx, dword ptr [ebp-14h]

0096174b mov eax, dword ptr [edX] // The first function address of the virtual table corresponds to the F1 Function

0096174d call eax // call F1

0096174f cmp esi, ESP

00961751 call @ ILT + 400 (_ rtc_checkesp) (961195 H)

Pvtbl-> F2 ();

00961756 mov eax, dword ptr [ebp-14h]

00961759 mov edX, dword ptr [eax]

0096175b mov ESI, ESP

0096175d mov ECx, dword ptr [ebp-14h]

00961760 mov eax, dword ptr [edX + 4] // virtual table address + 4 second function address F2 Function

00961763 call eax // call F2

00961765 cmp esi, ESP

00961767 call @ ILT + 400 (_ rtc_checkesp) (961195 H)

(Vtblreal1 *) pvtbl-> * PFn) (); // call the member function pointer

0096176c mov ESI, ESP

0096176e mov ECx, dword ptr [ebp-14h]

00961771 call dword ptr [ebp-2Ch] // This-> F2 (), ECx is the this pointer

00961774 cmp esi, ESP

00961776 call @ ILT + 400 (_ rtc_checkesp) (961195 H)

Delete pvtbl;

0096177b mov eax, dword ptr [ebp-14h]

0096177e mov dword ptr [ebp-128h], eax

00961784 mov ECx, dword ptr [ebp-128h]

0096178a mov dword ptr [ebp-134h], ECx

00961790 cmp dword ptr [ebp-134h], 0

00961797 je wmain + 11eh (9617aeh)

00961799 Push 1

0096179b mov ECx, dword ptr [ebp-134h]

009617a1 call ivtbl: 'scalar deleting destructor' (961064 h) // call the destructor to release resources

009617a6 mov dword ptr [ebp-1E4h], eax

009617ac JMP wmain + 128 H (9617b8h)

009617ae mov dword ptr [ebp-1E4h], 0

}

 

......

// VT to Diamond

// Ivtbl * pvtbl = new vtbldiamond (); // The conversion is not clear about vtblreal1 or vtblrealb ??? Tangle

Vtblreal1 * pvtblreal1 = new vtbldiamond ();

......

Vtblrealb * pvtbrealb = new vtbldiamond ();

00961950 push 38 H

00961952 call operator new (9611e0h)

00961957 add ESP, 4

0096195a mov dword ptr [ebp-170h], eax

00961960 mov dword ptr [ebp-4], 3

00961967 cmp dword ptr [ebp-170h], 0

0096196e je wmain + 2f3h (961983 H)

00961970 mov ECx, dword ptr [ebp-170h]

00961976 call vtbldiamond: vtbldiamond (961258 H)

0096197b mov dword ptr [ebp-1E4h], eax

00961981 JMP wmain + 2fdh (96198dh)

00961983 mov dword ptr [ebp-1E4h], 0

0096198d mov eax, dword ptr [ebp-1E4h]

00961993 mov dword ptr [ebp-17Ch], eax

00961999 mov dword ptr [ebp-4], 0 ffffffffh

009619a0 cmp dword ptr [ebp-17Ch], 0

009619a7 je wmain + 32ah (9619bah)

009619a9 mov ECx, dword ptr [ebp-17Ch]

009619af add ECx, 0ch

009619b2 mov dword ptr [ebp-1E8h], ECx

009619b8 JMP wmain + 334 H (9619c4h)

009619ba mov dword ptr [ebp-1E8h], 0

009619c4 mov edX, dword ptr [ebp-1E8h]

009619ca mov dword ptr [ebp-50h], EDX

If (pvtbrealb! = NULL)

009619cd cmp dword ptr [ebp-50h], 0

009619d1 je wmain + 39bh (961a2bh)

{

Ivtbl * pvtbl = dynamic_cast <ivtbl *> (pvtbrealb); // convert vtbldiamond type pointer to ivtbl pointer...

009619d3 mov eax, dword ptr [ebp-50h]

009619d6 mov dword ptr [pvtbl], eax

Pvtbl-> F1 ();

009619d9 mov eax, dword ptr [pvtbl]

009619dc mov edX, dword ptr [eax]

009619de mov ESI, ESP

009619e0 mov ECx, dword ptr [pvtbl]

009619e3 mov eax, dword ptr [edX]

009619e5 call eax

009619e7 cmp esi, ESP

009619e9 call @ ILT + 400 (_ rtc_checkesp) (961195 H)

Delete pvtbrealb;

009619ee mov eax, dword ptr [ebp-50h]

009619f1 mov dword ptr [ebp-158h], eax

009619f7 mov ECx, dword ptr [ebp-158h]

009619fd mov dword ptr [ebp-164h], ECx

00961a03 cmp dword ptr [ebp-164h], 0

00961a0a je wmain + 391 H (961a21h)

00961a0c Push 1

00961a0e mov ECx, dword ptr [ebp-164h]

00961a14 call vtblrealb: 'scalar deleting destructor' (961091 h) // see the following object analysis process

// The difference between declaring virtual destructor and declaring virtual destructor is not found in this experiment.

// If the virtual declarative destructor is not used in my environment, the VC debugger prompts that the assertions fail.

...

Object initialization Research

EBP 0x002ffb10

 

009616db push 0ch

009616dd call operator new (9611e0h)

009616e2 add ESP, 4

009616e5 mov dword ptr [ebp-140h], eax

 

Ebp-140h eax (pointer returned by operator new)

 

00961701 call vtblreal1: vtblreal1 (961_ch)

00961706 mov dword ptr [ebp-1E4h], eax

 

Ebp-1E4h eax (constructors return content)

 

EBP = 002ffb10

EBP-140H = 0x002ff9d0

The EBP-1E4H = 0x002ff92c

 

Let's see what both of them store?

0x002ff9d0 004b4f58 cccccccccc cccccccc

0x002ff92c 004b4f58 cccccccccc cccccccc

// Point to the same address? What is stored in it?

0x004b4f58 00967818 00000000 00000002 fdfdfdfd ababababab abababab 00000000

The address value does not have an initialized data region ....? Let's take a look.

0x00967818 009610d2 0096100a 00000000 009688a8 00961028 0096115e 00000000 009688c0 009610f0 00000000

The address seems to be an array ??

Vtblreal1: F1:

009610d2 JMP vtblreal1: F1 (961de0h)

 

Vtblreal1: F2:

0096100a JMP vtblreal1: F2 (961d70h)

 

Well, it turns out to be the function address of vtblreal1, so 0x00967818 is the virtual table address pointing to the vtblreal1 object.

The subsequent 00000000 and 00000002 represent vtblbase: m_baseval (0) and vtblreal1: m_dwvalue (2), respectively)

So we can draw a conclusion.

The new object and the structure returned by initialization both point to the vtblbase object address.

Let's start over. So what are the new and constructor doing here?

New initialization address memory is cdcdcdcd obviously not initialized

After the constructor is called

0x003f4f58 00da7818 00000000 00000002

Corresponding to the virtual table and member variables, it is certain that the constructor has completed object initialization.

Research on object structure Process

Vtblrealb: 'scalar deleting destructor ':

00da1091 JMP vtblrealb: 'scalar deleting destructor' (0da1c10h)

 

Vtblrealb: 'scalar deleting destructor ':

00da1c10 push EBP // address provided by VC

00da1c11 mov EBP, ESP

00da1c13 sub ESP, 0cch

00da1c19 push EBX

00da1c1a push ESI

00da1c1b push EDI

00da1c1c push ECx

00da1c1d Lea EDI, [ebp-0CCh]

00da1c23 mov ECx, 33 H

00da1c28 mov eax, 0 cccccccch

00da1c2d rep STOs dword ptr es: [EDI]

00da1c2f pop ECx

00da1c30 mov dword ptr [ebp-8], ECx

00da1c33 mov ECx, dword ptr [this]

00da1c36 call vtblrealb ::~ Vtblrealb (0da1_1 h) // call the vtblrealb destructor

00da1c3b mov eax, dword ptr [EBP + 8]

00da1c3e and eax, 1

00da1c41 je vtblrealb: 'scalar deleting destructor' + 3fh (0da1c4fh)

00da1c43 mov eax, dword ptr [this] // assign this pointer to the eax register

00da1c46 push eax

00da1c47 call operator Delete (0da10b4h) // call the delete function to delete

00da1c4c add ESP, 4 // stack balance

00da1c4f mov eax, dword ptr [this]

00da1c52 pop EDI

00da1c53 pop ESI

00da1c54 pop EBX

00da1c55 add ESP, 0cch

00da1c5b cmp ebp, ESP

00da1c5d call @ ILT + 400 (_ rtc_checkesp) (0da1195h)

00da1c62 mov ESP, EBP

00da1c64 pop EBP

00da1c65 RET 4

In this way, we can clearly observe how the compiler helps us to control the entire lifecycle of an object.

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.