[Disclaimer: All Rights Reserved. You are welcome to reprint it. Do not use it for commercial purposes. Contact Email: feixiaoxing @ 163.com]
The copy constructor and the copy function are two important functions in the class. What is the difference between the two? In fact, it is also very simple. For example, we can add a class definition:
Copy to clipboardprint? Class apple
{
Public:
Apple () {printf ("apple ()! \ N ");}
Apple (apple & a) {printf ("copy apple ()! \ N ");}
Apple & operator = (apple & a) {printf ("= apple () \ n"); return * this ;}
~ Apple () {printf ("~ Apple ()! \ N ");}
Void print () const {return ;}
};
Class apple
{
Public:
Apple () {printf ("apple ()! \ N ");}
Apple (apple & a) {printf ("copy apple ()! \ N ");}
Apple & operator = (apple & a) {printf ("= apple () \ n"); return * this ;}
~ Apple () {printf ("~ Apple ()! \ N ");}
Void print () const {return ;}
};
So what are the called functions in the following functions?
Copy to clipboardprint? Void process ()
{
Apple a, c;
Apple B =;
C = B;
}
Void process ()
{
Apple a, c;
Apple B =;
C = B;
} In fact, this is the result of the compilation. You can take a look at it and try to read it yourself. If you do not understand it at a time, you can read it several more times.
Copy to clipboardprint? 70: apple a, c;
0040127D lea ecx, [ebp-10h]
00401280 call @ ILT + 70 (apple: apple) (0040104b)
00401285 mov dword ptr [ebp-4], 0
0040128C lea ecx, [ebp-14h]
0040128F call @ ILT + 70 (apple: apple) (0040104b)
00401294 mov byte ptr [ebp-4], 1
71: apple B =;
00401298 lea eax, [ebp-10h]
0040129B push eax
0040129C lea ecx, [ebp-18h]
0040129F call @ ILT + 50 (apple: apple) (00401037)
004012A4 mov byte ptr [ebp-4], 2
72: c = B;
004012A8 lea ecx, [ebp-18h]
004012AB push ecx
004012AC lea ecx, [ebp-14h]
004012AF call @ ILT + 75 (apple: operator =) (00401050)
73 :}
004012B4 mov byte ptr [ebp-4], 1
004012B8 lea ecx, [ebp-18h]
004012BB call @ ILT + 0 (apple ::~ Apple) (00401005)
004012C0 mov byte ptr [ebp-4], 0
004012C4 lea ecx, [ebp-14h]
004012C7 call @ ILT + 0 (apple ::~ Apple) (00401005)
004012CC mov dword ptr [ebp-4], 0 FFFFFFFFh
004012D3 lea ecx, [ebp-10h]
004012D6 call @ ILT + 0 (apple ::~ Apple) (00401005)
004012DB mov ecx, dword ptr [ebp-0Ch]
004012DE mov dword ptr fs: [0], ecx
004012E5 pop edi
004012E6 pop esi
004012E7 pop ebx
004012E8 add esp, 58 h
004012EB cmp ebp, esp
004012ED call _ chkesp (004087c0)
004012F2 mov esp, ebp
004012F4 pop ebp
004012F5 ret
70: apple a, c;
0040127D lea ecx, [ebp-10h]
00401280 call @ ILT + 70 (apple: apple) (0040104b)
00401285 mov dword ptr [ebp-4], 0
0040128C lea ecx, [ebp-14h]
0040128F call @ ILT + 70 (apple: apple) (0040104b)
00401294 mov byte ptr [ebp-4], 1
71: apple B =;
00401298 lea eax, [ebp-10h]
0040129B push eax
0040129C lea ecx, [ebp-18h]
0040129F call @ ILT + 50 (apple: apple) (00401037)
004012A4 mov byte ptr [ebp-4], 2
72: c = B;
004012A8 lea ecx, [ebp-18h]
004012AB push ecx
004012AC lea ecx, [ebp-14h]
004012AF call @ ILT + 75 (apple: operator =) (00401050)
73 :}
004012B4 mov byte ptr [ebp-4], 1
004012B8 lea ecx, [ebp-18h]
004012BB call @ ILT + 0 (apple ::~ Apple) (00401005)
004012C0 mov byte ptr [ebp-4], 0
004012C4 lea ecx, [ebp-14h]
004012C7 call @ ILT + 0 (apple ::~ Apple) (00401005)
004012CC mov dword ptr [ebp-4], 0 FFFFFFFFh
004012D3 lea ecx, [ebp-10h]
004012D6 call @ ILT + 0 (apple ::~ Apple) (00401005)
004012DB mov ecx, dword ptr [ebp-0Ch]
004012DE mov dword ptr fs: [0], ecx
004012E5 pop edi
004012E6 pop esi
004012E7 pop ebx
004012E8 add esp, 58 h
004012EB cmp ebp, esp
004012ED call _ chkesp (004087c0)
004012F2 mov esp, ebp
004012F4 pop ebp
004012F5 ret
The Code is a bit long. For example, you can view the corresponding assembly code by 70, 71, 72, and 73 respectively:
(1) 70 sentences: we can see that the function has been called twice, which happens to be apple's constructor call. This also corresponds to two temporary variables a and c, the addresses of the two variables are [ebp-10] and [ebp-14], here we can see that the size of the entire class is 4 bytes, it is a common memory for storing data. The main reason why constructors can be bound with the corresponding memory is that ecx records the starting address of the memory, which is critical in C ++ compilation. We can see that the C ++ constructor seems to be not bound to the memory. In fact, the conventions have been made in VC. ecx is the this pointer, which is the class memory start address. If you are interested, let's take a look at the register that stores this pointer during G ++ compilation? (Actually eax)
(2) 71: The eax records the address of the referenced variable, and ecx is next to four bytes under ebp. However, the address of the function call is not the same as the default constructor, so we can guess that the constructor here is a copy constructor. We can check the Print message during debugging.
(3) 72 sentences: The 0x4012AF statement clearly tells us that the called function here is the operator = function, which is the reload of arithmetic operators, we will focus on this in our blog later.
(4) 73: as we have mentioned earlier, the Destructor are automatically called at the end of the function call. So here we see three calls appear? These three variables are exactly the three variables a, B, and c we mentioned earlier. So what is the order of the three variable calls? Let's look at the address of the variable, which is [ebp-18h], [ebp-14h], [ebp-10h], which is exactly the opposite order of the variable. So we can see that the Destructor and the constructor correspond exactly to each other, who appears first and then analyzes the constructor.