viewing C + + copy constructor __jquery from the perspective of reverse analysis

Source: Internet
Author: User

A section of C + + code:

: Howmany_2.cpp
#include <iostream>

using namespace std;

Class Howmany {
  static int objectcount;
  
Public:
  Howmany () {
    ++objectcount;
    Print ("Howmany ()");
  }
  ~howmany () {
    --objectcount;
    Print ("~howmany ()");
  }
  Howmany (const howmany& h) {
    ++objectcount;
    Print ("Howmany (const howmany&)");
  }
  
  void print (const char ss[]) {
    cout << ss << ":";
    cout << "Objectcount =" << objectcount << Endl;
    return;
  }
;

int howmany::objectcount = 0;

Howmany f (Howmany x) {
  x.print ("x argument inside F ()");
  cout << "return from F ()" << Endl;
  return x;  There is a return value x
}

int main () {
  {
    howmany h;
    cout << "Entering F ()" << Endl;
    Howmany H2 = f (h);
  }
  return 0;
} ///:~

Run Result:


Assembly Code:

38:int Main () {() {40:howmany h; 004017FD Lea Ecx,[h]; [h] is the memory address of Object H 00401800 call @ILT +685 (Howmany::howmany) (004012B2);
Call Constructor 00401805 mov dword ptr [ebp-4],0 41:cout << "entering F ()" << Endl; 0040180C Push offset @ILT +200 (Std::endl) (004010CD) 00401811 push offset string "entering F ()" (0046f090 00401816 Push offset std::cout (0047ce98) 0040181B call @ILT +660 (std::operator<<) (00401299); On the digression, look at the stack order 00401820 add esp,8 00401823 mov ecx,eax 00401825 call @ILT +480 (Std::basic_ostrea
M<char,std::char_traits<char> >::operator<<) (004011e5) 42:howmany H2 = f (h); 0040182A push ecx 0040182B mov ecx,esp;   Current ESP refers to the stack block as temporary object Temp memory address 0040182D mov dword ptr [EBP-18H],ESP 00401830 Lea Eax,[h] 00401833 push eax; Press H's memory address [h] onto the stack 00401834 call @ILT +0 (howmany::Howmany) (00401005);        Call copy constructor, copy h contents to temp memory 00401839 mov dword ptr [Ebp-1ch],eax 0040183C Lea ECX,[H2] 0040183F push ECX; Press the H2 memory address [H2] into the stack 00401840 call @ILT +640 (f) (00401285); Call F () function 00401845 add esp,8 00401848 mov dword ptr [EBP-20H],EAX: 0040184B Lea ecx,[ H2] 0040184E call @ILT +500 (Howmany::~howmany) (004011F9); Calling destructors, destroying H2 00401853 mov dword ptr [EBP-4],0FFFFFFFFH 0040185A Lea Ecx,[h] 0040185D call @ILT +500 (Howmany::~howmany) (004011F9);
Call destructor, destroy H://GetChar ();
45:return 0; 00401862 xor Eax,eax 46:}///:~



The working mechanism of the fun () function:

32:howmany f (Howmany x) {33:x.print ("x argument inside F ()"); 004015DB push offset string "x argument in     Side f () "(0046f030) 004015E0 Lea Ecx,[ebp+0ch] 004015E3 call @ILT +575 (howmany::p rint) (00401244) 34:
cout << "return from F ()" << Endl; 004015E8 Push offset @ILT +200 (Std::endl) (004010CD) 004015ED push offset string "return from F ()" (0046f
01c) 004015f2 push offset std::cout (0047ce98) 004015f7 call @ILT +660 (std::operator<<) (00401299) 004015FC add esp,8 004015FF mov ecx,eax 00401601 call @ILT +480 (std::basic_ostream<char,std
::char_traits<char> >::operator<<) (004011e5) 35:return x; 00401606 Lea Eax,[ebp+0ch]; [EBP+0C] is the memory address of temp 00401609 push eax 0040160A mov ecx,dword ptr [ebp+8]; [Ebp+8] is the H2 memory address, ECX points to the H2 memory block 0040160D call @ILT +0 (Howmany::howmany) (00401005); Call the copy constructor to copy the contents of temp to H2 memory 00401612  mov Ecx,dword ptr [ebp-10h] 00401615 or ecx,1 00401618 mov dword ptr [EBP-10H],ECX 0040161B mov byte ptr [ebp-4],0 0040161F Lea ecx,[ebp+0ch]; ECX Save Temp's memory address 00401622 call @ILT +500 (Howmany::~howmany) (004011F9); Call destructor, Destroy temp 00401627 mov eax,dword ptr [ebp+8]; EAX Save H2 memory address 36:}

For running results


Resolved as follows:

1. Object H Call Constructor

2. Output string "Entering F ()"

3. Before entering the F () function, a temporary object temp is created, the copy constructor is called, and the contents of object h are copied to temp

4. Enter the F () function, after executing the "return X" statement, call the copy constructor, copy the contents of the object temp to H2 (complete the work of H2 = f (h))

5. Call the destructor for temp before the end of the F () function, destroying the Temp object

6. Exit f () function, destroy object H2 before end of main function, destroy object h at last

----------------------------------------------------------------------------

"Howmany H2 = f (h)" is performed in reverse analysis; Record of stack distribution in statement procedure:

*****

Before entering the F () function (Create a Temp object, call the copy constructor, copy the contents of Object H to temp)



After entering the F () function



*********************************************************

Looking at a piece of code in the <<thinking in c++>>, the mechanism of copying the constructor is explained more clearly:

: Howmany_2.cpp #include <string> #include <iostream> using namespace std;
  Class Howmany {string name;
  
static int objectcount;
    Public:howmany (const string& id = "") {name = ID;
    ++objectcount;
  Print ("Howmany ()");
    } ~howmany () {--objectcount;
  Print ("~howmany ()");
    } howmany (const howmany& h) {name = H.name + ' copy ';
    ++objectcount;
  Print ("Howmany (const howmany&)");
    } void Print (const string& msg = "") {if (msg.length ()!= 0) {cout << msg << Endl;
    
    } cout << ' \ t ' << name << ': ' << ' objectcount = ' << objectcount << Endl;
  return;

}
};

int howmany::objectcount = 0;
  Howmany f (Howmany x) {x.print ("x argument inside F ()");
  cout << "return from F ()" << Endl;
return x;
    int main () {{Howmany h ("H");
    cout << "Entering F ()" << Endl;
    Howmany H2 = f (h); cout << "Call F" (), no return value "<< Endl;
    F (h);
  cout << "After called to F ()" << Endl;
  }//GetChar ();
return 0; } ///:~

Run Result:


Explained as follows:

1. Create object H and call the constructor

2. Output "Entering F ()" string

3. Before entering the F () function, create a temporary object temp and call the copy constructor to copy the contents of Object H to Temp

4. After entering the F () function, when "return X", call the copy constructor, copy the contents of the object temp to H2, call the destructor before the function ends, and destroy the object temp

5. Output string

6. Before entering the F () function, create a temporary object temp and call the copy constructor to copy the contents of Object H to Temp

7. After entering the F () function, create a temporary object x, call the copy constructor at "return x", copy the contents of the object temp to X, call the destructor before the function ends, destroy the object temp, and then destroy the object X

8. Before the end of the main function, call the destructor, destroy the object H2 first, then destroy the object H

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.