Thinking about forcing implicit conversion of this object to the base class in C ++

Source: Internet
Author: User

Objective C ++ is a classic book of C ++, but it cannot be regarded as a classic. Instead, you should take your own head to think about every clause in the book, only in this way can we make a difference.

The story happened in Clause 27 (do not perform any transformation actions as much as possible), and I am puzzled by the results produced by a piece of code.

Class window
{
Public:
Virtual void onresize (){...}
...
};

Class specialwindow: public window
{
Public:
Virtual void onresize ()
{
Static_cast <WINDOW> (* This). onresize ();
...
}
...
};

The book explains as follows: "As you expected, this code will convert * This to window. Therefore, the onresize function calls window: onresize. But I'm afraid you didn't expect it to call a function on the current object, it is the onresize on the temporary copy of the '* This object base class components' created by the transformation operation earlier! ".

Does static_cast <WINDOW> (* This) create a temporary window object? So I wrote the following code for testing.

000001 class window
000002 {
000003 protected:
000004 int _ w, _ H;
000005 public:
000006 window (const int W = 0, const int h = 0)
000007: _ w (W ),
000008 _ H (h)
000009 {
000010}
000011 virtual void onresize ()
000012 {
000013 _ w + = 10;
000014 _ H + = 10;
000015 cout <_ w <',' <_ H <Endl;
000016}
000017 };
000018
000019 class specialwindow: public window
000020 {
000021 public:
000022 virtual void onresize ()
000023 {
000024 static_cast <WINDOW> (* This). onresize ();
000025 // window: onresize ();
000026 cout <_ w <',' <_ H <Endl;
000027}
000028 };
000029
000030 int _ tmain (INT argc, _ tchar * argv [])
000031 {
000032 specialwindow SW;
000033 Sw. onresize ();
000034 return 0;
000035}

Then, I will disassemble the executable file to obtain the assembly code of the main function of the program:

: 00401000 ba0a000000 mov edX, 0000000a; ECx is the base address of the object
: 00401005 015104 add dword ptr [ECx + 04], EDX; <-_ w + = 10
: 00401008 015108 add dword ptr [ECx + 08], EDX; <-_ H + = 10
: 0040100b 8b4104 mov eax, dword ptr [ECx + 04]

The following code only executes the <_ w <',' <_ H <Endl

* Reference to: msvcp80 .? Endl @ STD @ yaaav? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ 1 @ aav21 @ Z, ord: 0799 H
|
: 0040100e 8b1538204000 mov edX, dword ptr [0, 00402038]
: 00401014 8b4908 mov ECx, dword ptr [ECx + 08]
: 00401017 52 push edX
: 00401018 51 push ECx

* Reference to: msvcp80 .? Cout @ STD @ 3 V? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ 1 @ A, ord: 0675 H
|
: 00401019 8b0d50204000 mov ECx, dword ptr [0, 00402050]
: 0040101f 50 push eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401020 ff1544204000 call dword ptr [00402044]
: 00401026 50 push eax
: 00401027 e8d4010000 call 00401200
: 0040102c 83c404 add ESP, 00000004
: 0040102f 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401031 ff1544204000 call dword ptr [00402044]
: 00401037 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ p6aaav01 @ aav01 @ z @ Z, ord: 0318 H
|
: 00401039 ff1540204000 call dword ptr [00402040]
: 0040103f C3 RET

If static_cast is replaced with the commented-out window: onresize, the following disassembly code is obtained:

* Reference to: msvcp80 .? Endl @ STD @ yaaav? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ 1 @ aav21 @ Z, ord: 0799 H
|
: 00401000 8b1538204000 mov edX, dword ptr [0, 00402038]
: 00401006 56 push ESI
: 00401007 8bf1 mov ESI, ECx; Because ECx is needed to save function call Parameters
: 00401009 b90a000000 mov ECx, 0000000a; therefore, the base address of the object is stored in ESI.
: 0040100e 014e04 add dword ptr [ESI + 04], ECx; _ w + = 10
: 00401011 014e08 add dword ptr [ESI + 08], ECx; _ H + = 10
: 00401014 8b4e08 mov ECx, dword ptr [ESI + 08]
: 00401017 8b4604 mov eax, dword ptr [ESI + 04]
: 0040101a 52 push edX
: 0040101b 51 push ECx

The following code calls the output twice on the same object. After _ w and _ H increase by 10 for the first time and then after the first time, it indicates that window is called first :: onresize: Continue to output code in specialwindow: onresize.

* Reference to: msvcp80 .? Cout @ STD @ 3 V? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ 1 @ A, ord: 0675 H
|
: 0040101c 8b0d50204000 mov ECx, dword ptr [0, 00402050]
: 00401022 50 push eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401023 ff1544204000 call dword ptr [00402044]
: 00401029 50 push eax
: 0040102a e8b1010000 call 004011e0
: 0040102f 83c404 add ESP, 00000004
: 00401032 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401034 ff1544204000 call dword ptr [00402044]
: 0040103a 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ p6aaav01 @ aav01 @ z @ Z, ord: 0318 H
|
: 0040103c ff1540204000 call dword ptr [0, 00402040]
: 00401042 a138204000 mov eax, dword ptr [0, 00402038]
: 00401047 8b4e08 mov ECx, dword ptr [ESI + 08]
: 0040104a 8b5604 mov edX, dword ptr [ESI + 04]
: 0040104d 50 push eax
: 0040104e 51 push ECx

* Reference to: msvcp80 .? Cout @ STD @ 3 V? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ 1 @ A, ord: 0675 H
|
: 0040104f 8b0d50204000 mov ECx, dword ptr [0, 00402050]
: 00401055 52 push edX

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401056 ff1544204000 call dword ptr [00402044]
: 0040105c 50 push eax
: 0040105d e87e010000 call 004011e0
: 00401062 83c404 add ESP, 00000004
: 00401065 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ H @ Z, ord: 0311 H
|
: 00401067 ff1544204000 call dword ptr [00402044]
: 0040106d 8bc8 mov ECx, eax

* Reference to: msvcp80 .?? 6? $ Basic_ostream @ du? $ Char_traits @ d @ STD @ qaeaav01 @ p6aaav01 @ aav01 @ z @ Z, ord: 0318 H
|
: 0040109f ff1540204000 call dword ptr [00402040]
: 00401075 5E pop ESI
: 00401076 C3 RET

Through analysis and comparison, it is learned that static_cast <WINDOW> (* This) splits the object itself into a base class object. After calling onresize, the object considers itself as a window object, so we get the disassembly result above.

However, I do not know how to explain the first case. The output result is: 10, 10 [line feed] 0, 0. Because cout is called only once in the disassembly code !?

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.