Can a constructor in C + + call a virtual function? (The answer is syntax Yes, output error), but Java can actually

Source: Internet
Author: User
Tags object model

Environment: XPSP3 VS2005

Today the black general to the candidate out of a C + + constructor call virtual function, the specific topic is more complex than the title, the general situation can see the following code:

[CPP]View PlainCopy
  1. Class Base
  2. {
  3. Public
  4. Base ()
  5. {
  6. Fuction ();
  7. }
  8. virtual void fuction ()
  9. {
  10. cout << "base::fuction" << Endl;
  11. }
  12. };
  13. Class A: Public Base
  14. {
  15. Public
  16. A ()
  17. {
  18. Fuction ();
  19. }
  20. virtual void fuction ()
  21. {
  22. cout << "a::fuction" << Endl;
  23. }
  24. };
  25. What is the output of defining an object of a?
  26. A;

First answer the question of the title, the call is of course no problem, but to get the results you want? Or what kind of results do you want?

Some say it will output:

[HTML]View PlainCopy
    1. A::fuction
    2. A::fuction

If this is the case, first we review the C + + object model in the construction sequence, when constructing a subclass object, the first will construct its base class, if there is a multi-level inheritance relationship, in fact, from the top-level base class down-to-bottom structure (virtual inheritance, multiple inheritance is not discussed here), if the above situation is output , that is, when the base is constructed, that is, when calling Fuction in the constructor of base, the fuction of subclass A is called, and a is not actually started, so the behavior of the function is completely unpredictable, so this is obviously not the case, the actual output is:

[HTML]View PlainCopy
    1. Base::fuction
    2. A::fuction

It is said to be the last output in Java (it feels a bit strange).

Let's take a closer look at what's going on. In the constructor of a, the constructor of base is called first, and the constructor of base is as follows:

Class Base
{
Public
Base ()
00411600 Push EBP
00411601 mov Ebp,esp
00411603 Sub Esp,0cch
00411609 push EBX
0041160A push ESI
0041160B Push EDI
0041160C push ECX
0041160D Lea EDI,[EBP-0CCH]
00411613 mov ecx,33h
00411618 mov eax,0cccccccch
0041161D Rep STOs dword ptr Es:[edi]
0041161F pop ECX
00411620 mov dword ptr [EBP-8],ECX
00411623 mov Eax,dword ptr [this]
00411626 mov dword ptr [eax],offset Base:: ' vftable ' (41770Ch)
{
Fuction ();
0041162C mov Ecx,dword ptr [this]
0041162F call Base::fuction (4111a9h)

 }
00411634  mov         eax,dword ptr [this] 
00411637   pop         edi  
00411638  pop          esi  
00411639  pop          ebx  
0041163a  add         esp,0CCh 
00411640  cmp         ebp,esp 
00411642  call         @ILT +460 (__RTC_CHECKESP) (4111d1h)  
00411647  mov          esp,ebp 
00411649  pop          ebp  
0041164a  ret

From the single-step tracking, notice the black bold part of the assembly code, ECX is the address of the object (0X0012FF60, the case on my machine, there is a picture of the truth), the first is to set vtable address to the first four bytes of the object (different compilers may be different), Then directly call the Base::fuction function, and there is no virtual mechanism, and we look at the state of the virtual table, the virtual table has been filled with 0x4111a9, note the address of the virtual table 0x0041770c, At this point, the object address 0x0012ff60 the first four bytes to be stored is the 0x0041770c.

Continue tracing, the process goes back to the constructor of a, again notice the bold part of the code, from the base class base of the constructor returned, in A's constructor, the virtual table pointer is reset, now the virtual table pointer is (0x417700h), the same call Fuction when a direct call to a:: The Fuction function does not use a virtual mechanism, and the 0x41110e where the virtual table 0x417700h points is the a::fuction address.

Class A:public Base
{
Public
A ()
00411590 Push EBP
00411591 mov Ebp,esp
00411593 Sub Esp,0cch
00411599 push EBX
0041159A push ESI
0041159B Push EDI
0041159C push ECX
0041159D Lea EDI,[EBP-0CCH]
004115A3 mov ecx,33h
004115A8 mov eax,0cccccccch
004115AD Rep STOs dword ptr Es:[edi]
004115AF pop ECX
004115B0 mov dword ptr [EBP-8],ECX
004115B3 mov Ecx,dword ptr [this]
004115b6 call Base::base (411140h)
004115BB mov Eax,dword ptr [this]
004115BE mov dword ptr [eax],offset A:: ' vftable ' (417700h)
{
Fuction ();
004115C4 mov Ecx,dword ptr [this]
004115c7 call A::fuction (41110Eh)
}
004115CC mov Eax,dword ptr [this]
004115CF Pop EDI
004115d0 pop ESI
004115D1 pop ebx
004115D2 Add ESP,0CCH
004115D8 CMP EBP,ESP
004115DA call @ILT +460 (__RTC_CHECKESP) (4111D1H)
004115DF mov esp,ebp
004115E1 Pop EBP
004115E2 ret


In fact, it is so simple.

http://blog.csdn.net/magictong/article/details/6734241

Can a constructor in C + + call a virtual function? (The answer is syntax Yes, output error), but Java can actually

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.