A piece of C ++ code:
//: Howmany_2.cpp # include <iostream> using namespace STD; Class howcounter {static int objectcount; public: howcounter () {++ objectcount; print ("howcounter ()");} ~ Howcounter () {-- objectcount; print ("~ Howmany () ");} howmany (const howmany & H) {++ objectcount; print (" howprint (const howmany &)");} void print (const char ss []) {cout <SS <":"; cout <"objectcount =" <objectcount <Endl; return ;}}; int howcount: objectcount = 0; howmany F (howmany X) {X. print ("x argument inside f ()"); cout <"return from F ()" <Endl; return X; // return value x} int main () {howmany h; cout <"entering F ()" <End L; how1_h2 = f (h);} return 0 ;}///:~
Running result:
Assembly code:
38: int main () {39: {40: how1_h; 004017fd Lea ECx, [H]; [h] for object h memory address 00401800 call @ ILT + 685 (howmany: howmany) (004012b2); Call constructor 00401805 mov dword ptr [ebp-4], 041: 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); digress, observe Next stack order 00401820 add ESP, 800401823 mov ECx, eax00401825 call @ ILT + 480 (STD: basic_ostream <char, STD: char_traits <char >:: operator <) (004011e5) 42: how1_h2 = f (h); 0040182a push ecx0040182b mov ECx, esp; current ESP refers to the stack block as the temporary object temp memory address 0040182d mov dword ptr [ebp-18h], esp00401830 Lea eax, [H] 00401833 push eax; press the memory address [h] of H into the stack 00401834 call @ ILT + 0 (howmany: howmany) (00401005); call the copy constructor, copy the content of H to the temp memory 00401839. MoV dword ptr [ebp-1Ch], eax0040183c Lea ECx, [H2] 0040183f push ECx; push H2 Memory Address [H2] into Stack 00401840 call @ ILT + 640 (f) (00401285); call f () function 00401845 add ESP, 800401848 mov dword ptr [ebp-20h], eax43:} 0040184b Lea ECx, [H2] 0040184e call @ ILT + 500 (how4e: :~ Howptr) (004011f9); call the destructor to destroy the h200401853 mov dword ptr [ebp-4], 0ffffffh0040185a Lea ECx, [H] 0040185d call @ ILT + 500 (howmany ::~ Howmany) (004011f9); call the destructor to destroy h44: // getchar (); 45: Return 0; 00401862 XOR eax, eax46 :}///:~
The working mechanism of fun () functions:
32: how1_f (how1_x) {33: X. print ("x argument inside f ()"); 004015db push offset string "x argument inside f ()" (0046f030) 004015e0 Lea ECx, [EBP + 0ch] 004015e3 call @ ILT + 575 (howmany: print) (00401244) 34: cout <"return from F ()" <Endl; 004015e8 push offset @ ILT + 200 (STD: Endl) (004010cd) 004015ed push offset string "return from F ()" (0046f01c) 004015f2 push offset STD: cout (0047ce98) 004015f7 call @ ILT + 660 (STD: Operator <) (00401299) 004015fc add ESP, 8004015ff mov ECx, eax00401601 call @ ILT + 480 (STD: basic_ostream <char, STD :: char_traits <char >:: operator <) (004011e5) 35: Return X; 00401606 Lea eax, [EBP + 0ch]; [EBP + 0C] For temp memory address 00401609 push eax0040160a mov ECx, dword ptr [EBP + 8]; [EBP + 8] for H2 memory address, ECX points to the H2 memory block 0040160d call @ ILT + 0 (howmany: howmany) (00401005); call the copy constructor to copy the temp content to the H2 memory 00401612 mov ECx, Dword ptr [ebp-10h] 00401615 or ECX, 100401618 mov dword ptr [ebp-10h], ecx0040161b mov byte PTR [ebp-4], 00040161f Lea ECx, [EBP + 0ch]; ECX saves the temp memory address 00401622 call @ ILT + 500 (howtraffic ::~ Howmany) (004011f9); call the destructor to destroy temp00401627 mov eax, dword ptr [EBP + 8]; eax saves H2 memory address 36 :}
For running results
Resolution:
1. Object H calls Constructor
2. Output string "entering F ()"
3. before entering the F () function, create a temporary object temp, call the copy constructor, and copy the content of object h to temp.
4. enter the F () function. After the "Return X" statement is executed, call the copy constructor to copy the temp content of the object to H2 (H2 = f (H) is completed))
5. Before the F () function ends, call the Destructor for temp to destroy the temp object.
6. Exit the F () function. Before the main function ends, destroy the object H2 and the object H.
----------------------------------------------------------------------------
Records of stack distribution during Reverse Analysis:
*****
Before entering the F () function (create a temporary object temp, call the copy constructor, and copy the content of object h to temp)
After entering the F () function
**************************************** *****************
Let's look at a piece of code in <thinking in C ++> to explain more clearly the mechanism of copying constructor:
//: 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 call to f()" << endl; } // getchar(); return 0;} ///:~
Running result:
Explanation:
1. Create object H and call the constructor
2. output the "entering F ()" String
3. before entering the F () function, create a temporary object temp and call the copy constructor to copy the content of object h to temp.
4. after entering the F () function, when "Return X", call the copy constructor to copy the temp content of the object to H2, and call the Destructor before the function ends, destroy object temp
5. Output string
6. before entering the F () function, create a temporary object temp and call the copy constructor to copy the content of object h to temp.
7. after entering the F () function, create a temporary object X. When "Return X", call the copy constructor to copy the temp content of the object to X, call the Destructor before the function ends. first destroy the object temp and then destroy the object X.
8. Before the main function ends, call the destructor. Destroy the object H2 first, and then destroy the object H.