Disassembly exploring the mechanism of realizing polymorphism of C + + virtual function

Source: Internet
Author: User

Virtual function is a mechanism for implementing polymorphism in C + +, so how does it do it?


The following is an disassembly to explore the virtual function memory model, to see virtual functions to achieve polymorphic process.


Tools

Visual Studio: The following programs only do the VC + + compiler under the 32-bit program discussion, the other compiler and 64-bit program differences are not discussed.


Disassembly process

First, declare a simple C + + class that does not contain a virtual function, as follows:

650) this.width=650; "src=" https://pic2.zhimg.com/v2-b1008892bbf0c2bae4656af2f9f701a9_b.jpg "class=" content_image Lazy "width=" 372 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', Sans-serif;font-size:medium;white-space: Normal;background-color:rgb (255,255,255); "alt=" v2-b1008892bbf0c2bae4656af2f9f701a9_b.jp "/>

Add a breakpoint to the constructor to make the disassembly constructor code,

650) this.width=650; "src=" https://pic3.zhimg.com/v2-8dd0b464dd77e7f329d0e17280525e46_b.jpg "class=" content_image Lazy "width=" 267 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', Sans-serif;font-size:medium;white-space: Normal;background-color:rgb (255,255,255); "alt=" v2-8dd0b464dd77e7f329d0e17280525e46_b.jp "/>

When running to a breakpoint, use the shortcut key ctrl+f11 in Visual Studio to open the disassembly to the following command:

650) this.width=650; "src=" https://pic4.zhimg.com/v2-f8beed6b0e8d163c7837c0ec7f71c8b3_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" 805 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-f8beed6b0e8d163c7837c0ec7f71c8b3_b.jp "/ >

The instructions in the yellow box show that the 4 value in the constructor is placed in the first 4 bytes of the area pointed to by the this pointer, and that the value of 4 is exactly the value of the variable A, that is, when a virtual function is not included, the 4-byte-length int variable A is stored in the starting 4 bytes of the object data space .


The class C2 that contains the virtual function is then created,

650) this.width=650; "src=" https://pic2.zhimg.com/v2-13d8d5072b3965de705daa1b3f2e3ef1_b.jpg "class=" content_image Lazy "width=" 403 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', Sans-serif;font-size:medium;white-space: Normal;background-color:rgb (255,255,255); "alt=" v2-13d8d5072b3965de705daa1b3f2e3ef1_b.jp "/>

Use the same method to let the program pause the breakpoint on the constructor of the C2 class, and then disassemble, while comparing the C1 disassembly instructions:

650) this.width=650; "src=" https://pic3.zhimg.com/v2-b53e0f26e685b867054ea87850ccd28a_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" 1164 "style=" margin:24px auto; "alt=" v2-b53e0f26e685b867054ea87850ccd28a_b.jp "/> The left is a class C2 that contains virtual functions, and the right side is a class that does not contain virtual functions C1

As you can see, the constructor of the class C2 that contains the virtual function, compared to the class C1 that does not contain the virtual function, only has two more instructions:

650) this.width=650; "src=" https://pic2.zhimg.com/v2-f9228c3412c0485e347b90a589ed3b45_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" 540 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-f9228c3412c0485e347b90a589ed3b45_b.jp "/ >

These two instructions indicate that the first 4 bytes of the this pointer are no longer stored in variable a, but rather a vftable address (that is, a virtual function table), while the variable data is stored by a backward 4 bytes, as shown in the figure on the left, all addresses are offset with 4来:

650) this.width=650; "src=" https://pic1.zhimg.com/v2-053883116bd21c5824e5dbd0d31890dc_b.jpg "class=" content_image Lazy "width=" 377 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', Sans-serif;font-size:medium;white-space: Normal;background-color:rgb (255,255,255); "alt=" v2-053883116bd21c5824e5dbd0d31890dc_b.jp "/>

This allows you to summarize the in-memory model of class objects that contain virtual functions:

650) this.width=650; "src=" https://pic1.zhimg.com/v2-f083c1e7102fc9f44c803e7fb68fdbc4_b.jpg "class=" content_image Lazy "width=" 199 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', Sans-serif;font-size:medium;white-space: Normal;background-color:rgb (255,255,255); "alt=" v2-f083c1e7102fc9f44c803e7fb68fdbc4_b.jp "/>

, the class object that contains the virtual function, where the first 4 bytes hold the virtual function table, and then the variables are stored later.


So what is stored in the virtual function table?

From the picture above, the virtual function table points to the memory address is 3B 8B 34h, through the Visual Studio debugging-Windows-memory, open the memory viewing tool, navigate to this address, you can see the contents:

650) this.width=650; "src=" https://pic3.zhimg.com/v2-b3deea0fa4a361670c12cf6e9fc45be2_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" 771 "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-b3deea0fa4a361670c12cf6e9fc45be2_b.jp "/ >

It is obvious that the selected 8 bytes represent two segments of memory address 3b 0a and 3b AC, not the program instruction set, because the memory address of the program data is in the "3b * * * * * * * * * * * *, you can see all disassembly instructions before the memory address is the same.


In order to figure out the contents of these two memory addresses, enter the memory address in the Disassembly window to view 3b 0a:

650) this.width=650; "src=" https://pic2.zhimg.com/v2-5656c07e1603929a35b44d2c44596391_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-5656c07e1603929a35b44d2c44596391_b.jp "/ >

As you can see, this address points to the first virtual function c2::test () and then to the second address 3b AC:

650) this.width=650; "src=" https://pic4.zhimg.com/v2-ae34c039e6b4b619bbd0deef339a1f57_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-ae34c039e6b4b619bbd0deef339a1f57_b.jp "/ >

As you can see, the second address points to the second virtual function, C2::test2 ().

This means that the virtual function table is actually an array of virtual function pointers .


So how did the polymorphism come true?

Then create a subclass CC2 that inherits C2, and similarly disassemble the view constructor:

650) this.width=650; "src=" https://pic1.zhimg.com/v2-36fb95f9e4bc627ca49e9a027da7fdec_b.jpg "class=" origin_image Zh-lightbox-thumb lazy "width=" "style=" margin:24px Auto;color:rgb (51,51,51); font-family: '-apple-system ', ' Helvetica Neue ', Arial, ' Pingfang SC ', ' Hiragino Sans GB ', ' Microsoft yahei ', ' Wenquanyi Micro Hei ', sans-serif;font-size: Medium;white-space:normal;background-color:rgb (255,255,255); "alt=" v2-36fb95f9e4bc627ca49e9a027da7fdec_b.jp "/ >

It can be seen that thevirtual function table address given in the Cc2 constructor is different from the base class address, and the virtual function pointed to is also cc2 own virtual function, in the Cc2 constructor, first called the base class C2 constructor, as shown in the red box, in the base class C2 constructor, The virtual function table of the base class is placed in the first 4 bytes of the class object, then comes out from the C2 constructor, runs to the yellow box section, and the subclass will again place the subclass's own virtual function table in the first 4 bytes of the class object, thereby overwriting the virtual function table of the base class to achieve polymorphism .


Summarize

Classes that do not contain virtual functions are not virtual function tables, and data such as variables are stored from the first byte of a class object's data block.

The class containing the virtual function will have a virtual function table, and the first 4 bytes of the class object data block are stored in the virtual function table address, starting from the 5th byte to store variables and other data.


The virtual function table is essentially an array of function pointers that hold pointers to the various virtual functions of this class.


Because the constructor of the base class executes before the subclass, this causes the virtual function table of the subclass to subtly overwrite the virtual function table of the base class to achieve polymorphism.


This article from "Little White Father" blog, reproduced please contact the author!

Disassembly exploring the mechanism of realizing polymorphism of C + + virtual function

Related Article

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.