I think the Implementation of Virtual inheritance in vc6

Source: Internet
Author: User
I think the Implementation of Virtual inheritance in vc6

I tried it over the past two days.

Because there is only the vc6 compiler in hand, we only read the vc6 method.

My test procedure is as follows:
# Include "stdafx. H"
Class mostbase1
{
Public:
Mostbase1 (): I (1 ){};
Int I;
};
Class mostbase2
{
Public:
Mostbase2 (): J (2 ){};
Int J;
};

Class base1: Public Virtual mostbase1, Public Virtual mostbase2
{
};
Class base2: Public Virtual mostbase1, Public Virtual mostbase2
{
};
Class derived: Public base1, public base2
{
};
Void F (derived * pderived)
{
Mostbase1 * pbase1 = pderived;
Mostbase2 * pbase2 = pderived;
Int K = pderived-> I;
K = pderived-> J;
K = pbase1-> I;
K = pbase2-> J;
}
Int main (INT argc, char * argv [])
{
Derived D;
F (& D );
Printf ("Hello world! ");
Return 0;
}
After my tests and views of the assembly code, I learned that VC's virtual base class conversion is indeed implemented by using a virtual base class table in the C ++ objects model.
Each of base1 and base2 has a _ vbct _ PTR (4 bytes in size) to point to a virtual base class table, this table stores the offset of the base class's virtual base class in the base class, followed by the data. When derived inherits from base1 and base2, it first stores the _ vbct_ptr of base1 and base2, then, put the data of base1 and base2 in the same base class together.
The base1 class memory layout is as follows (base2 and base1 are the same ):
Pvoid * _ vbct_base1 ---- first, the address of the virtual base table. The data of _ vbct_base1 is as follows:
---- 00 00 00 00 04 00 00 08 00 00 00
---- The offset of mostbase1 in base1 is the value of [_ vbct_base1 + 4 ].
Int I; ---- I in the mostbase1 class
Int J; ---- J in the mostbase2 class

The memory layout of the derived class is as follows:
Pvoid * _ vbct_base1; ---- address of the virtual base table of the base1 class. The value of the table varies according to the following data:
---- 00 00 00 00 08 00 00 00 0C 00 00 00
Pvoid * _ vbct_base2; ---- address of the virtual base table of the base2 class. The data is as follows:
---- 00 00 00 00 04 00 00 08 00 00 00
Int I;
Int J;

 

The following is the assembly code of the F (derived * pderived) function.

29: void F (derived * pderived)
30 :{
0040c230 push EBP
0040c231 mov EBP, ESP
0040c233 sub ESP, 60 h
0040c236 push EBX
0040c237 push ESI
0040c238 push EDI
0040c239 Lea EDI, [ebp-60h]
0040c23c mov ECx, 18 h
0040c241 mov eax, 0 cccccccch
0040c246 rep STOs dword ptr [EDI]
31: mostbase1 * pbase1 = pderived;
0040c248 cmp dword ptr [EBP + 8], 0 [1]
0040c24c jne f + 27 h (0040c257)
0040c24e mov dword ptr [ebp-18h], 0 [2]
0040c255 jmp f + 35 h (0040c265)
0040c257 mov eax, dword ptr [EBP + 8]
0040c25a mov ECx, dword ptr [eax] [3]
0040c25c mov edX, dword ptr [EBP + 8]
0040c25f add edX, dword ptr [ECx + 4] [4]
0040c262 mov dword ptr [ebp-18h], EDX
0040c265 mov eax, dword ptr [ebp-18h]
0040c268 mov dword ptr [ebp-4], eax [5]
32: mostbase2 * pbase2 = pderived;
0040c26b cmp dword ptr [EBP + 8], 0
0040c26f jne f + 4ah (0040c27a)
0040c271 mov dword ptr [ebp-1Ch], 0 [6]
0040c278 jmp f + 58 h (0040c288)
0040c27a mov ECx, dword ptr [EBP + 8]
0040c27d mov edX, dword ptr [ECx] [7]
0040c27f mov eax, dword ptr [EBP + 8]
0040c282 add eax, dword ptr [edX + 8] [8]
0040c285 mov dword ptr [ebp-1Ch], eax
0040c288 mov ECx, dword ptr [ebp-1Ch]
0040c28b mov dword ptr [ebp-8], ECx
33: base1 * P1 = pderived;
0040c28e mov edX, dword ptr [EBP + 8]
0040c291 mov dword ptr [ebp-0Ch], EDX [9]
34: P1-> I = 1;
0040c294 mov eax, dword ptr [ebp-0Ch]
0040c297 mov ECx, dword ptr [eax]
0040c299 mov edX, dword ptr [ECx + 4] [10]
0040c29c mov eax, dword ptr [ebp-0Ch]
0040c29f mov dword ptr [eax + EDX], 1
35: base2 * P2 = pderived;
0040c2a6 cmp dword ptr [EBP + 8], 0
0040c2aa je F + 87 h (0040c2b7)
0040c2ac mov ECx, dword ptr [EBP + 8]
0040c2af add ECx, 4 [11]
0040c2b2 mov dword ptr [ebp-20h], ECx
0040c2b5 jmp f + 8eh (0040c2be)
0040c2b7 mov dword ptr [ebp-20h], 0
0040c2be mov edX, dword ptr [ebp-20h]
0040c2c1 mov dword ptr [ebp-10h], EDX [12]
36: P2-> j = 1;
0040c2c4 mov eax, dword ptr [ebp-10h]
0040c2c7 mov ECx, dword ptr [eax]
0040c2c9 mov edX, dword ptr [ECx + 8] [13]
0040c2cc mov eax, dword ptr [ebp-10h]
0040c2cf mov dword ptr [eax + EDX], 1
37: int K = pderived-> I;
0040c2d6 mov ECx, dword ptr [EBP + 8]
0040c2d9 mov edX, dword ptr [ECx]
0040c2db mov eax, dword ptr [edX + 4] [14]
0040c2de mov ECx, dword ptr [EBP + 8]
0040c2e1 mov edX, dword ptr [ECx + eax] [15]
0040c2e4 mov dword ptr [ebp-14h], EDX
38: K = pderived-> J;
0040c2e7 mov eax, dword ptr [EBP + 8]
0040c2ea mov ECx, dword ptr [eax]
0040c2ec mov edX, dword ptr [ECx + 8] [16]
0040c2ef mov eax, dword ptr [EBP + 8]
0040c2f2 mov ECx, dword ptr [eax + EDX]
0040c2f5 mov dword ptr [ebp-14h], ECx
39:
40 :}
0040c2f8 pop EDI
0040c2f9 pop ESI
0040c2fa pop EBX
0040c2fb mov ESP, EBP
0040c2fd pop EBP
0040c2fe RET

[1] dword ptr [EBP + 8 h] Is pderived. check whether it is null.
[2] dword ptr [ebp-18h] is an intermediate variable that is also assigned null when pderived is null
[3] retrieve _ vbct_base1 at the beginning of the derived class
[4] Get the offset of the mostbast1 class in derived. The value occupies 4 bytes at the position of _ vbct_base1 + 4, and the value is 8, because there are two _ vbct_prt before derived, therefore, the offset of mostbast1 in derived is 8.
[5] assign pbase1 values, dword ptr [ebp-4] Stores pbase1;
[6] Same as (2), but the address of the intermediate variable is different
[7] Same as (3), retrieve _ vbct_base1
[8] Same as (4), get the offset of mostbast2 in derived, which is 12
[9] retrieve the address of base1 In the derived class, that is, the address of _ vbct_base1 in derived. If you have any questions, refer to the following:
[10] When you use P1 to access data, you can use _ vbct_base1 to get the offset of mostbase1 in derived through _ vbct_base1. The final address obtained is pderived + 8.
[11] Now we can retrieve the _ vbct_base2 address. Have you seen add ECx, 4?
[12] assigning P2 values
[13] Get the mostbase2 address through _ vbct_base2, and then access J
[14] Get the mostbase1 address through _ vbct_base1
[15] The offset is in eax.
[16] Get the mostbase2 address through _ vbct_base1

The following is the c pseudo code I have conceived. It may be incorrect because the assembly code has been optimized.
Void F (derived * pderived)
{
---- Mostbase1 * pbase1 = pderived;
Mostbase1 * pbase1, * temp1;
If (pderived = 0)
{
Temp1 = 0;
}
Else
{
Temp1 = (mostbase1 *) (pderived + (pderived->__ vbct_base1 [1]);
}
Pbase1 = temp1;

---- Mostbase2 * pbase2 = pderived;
Mostbase2 * pbase2, * temp2;
If (pderived = 0)
{
Temp2 = 0;
}
Else
{
Temp2 = (mostbase2 *) (pderived + (pderived->__ vbct_base1 [2]);
}
Pbase2 = temp2;
---- Base1 * P1 = pderived;
Base1 * P1 = & pderived->__ vbct_base1;
---- P1-> I = 1;
(Mostbase1 *) (P1 + p1->__ vbct_base1 [1])-> I = 1;
---- Base2 * P2 = pderived;
Base2 * P2 = & pderived->__ vbct_base2;
---- P2-> j = 1;
(Mostbase2 *) (P2 + P2->__ vbct_base2 [2])-> j = 1;
---- Int K = pderived-> I;
Int K = (mostbase1 *) (pderived + pderived->__ vbct_base1 [1])-> I;
---- K = pderived-> J;
K = (mostbase2 *) (pderived + pderived->__ vbct_base1 [2])-> J;
}

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.