链 接:http://bbs.pediy.com/showthread.php?t=87589
进入本次正题:
(三)[ C++ 之 构造与析构 ]
//来CPP:
//stack3.h
#ifndef STACK_H_
#define STACK_H_
class stack
{
struct link
{
void *data;
link *next;
void initialize(void *Data, link *Next);
} *head;
public:
stack();
stack(int);
~stack();
void push(void *Data);
void* peek(void *Data);
void* pop();
};
#endif
//stack3.cpp
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include “stack3.h”
void stack::link::initialize(void *Data, link *Next)
{
data = Data;
next = Next;
}
stack::stack()
{
printf(“stack::stack() called . \n”);
head = 0;
}
stack::stack(int){}
void stack::push(void *Data)
{
link *newLink = (link*)malloc(sizeof(link));
assert(newLink);
newLink->initialize(Data,head);
head = newLink ;
}
void* stack::peek(void *Data){return head->data;}
void* stack::pop()
{
if (0 == head) return 0;
void *result =head->data;
link *oldHead = head;
head = head->next;
free(oldHead);
return result;
}
stack::~stack()
{
printf(“stack::~stack() called . \n”);
link *cursor = head;
while(head)
{
cursor = cursor->next;
free(head);
head = cursor;
}
}
// lesson3.cpp : Defines the entry point for the console application.
//
//#include “stdafx.h”
#include “stack3.h”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#pragma warning(disable:4005)
#pragma warning(disable:4700)
#define PPATH “c:\\test.txt”
#define BUFSIZE 100
int main(int argc, char* argv[])
{
__asm int 3
assert(2 == argc) ;
FILE *file = fopen(PPATH,”r”);
assert(file);
printf(“1\n”);
{printf(“2\n”); stack test; printf(“3\n”);}
printf(“4\n”);
printf(“sizeof stack :%d”,sizeof(stack));
char buf[BUFSIZE];
buf[9] += 9 ;
stack textline; //Constuctor called.
while (fgets(buf,BUFSIZE,file))
{
char *str = (char *)malloc(strlen(buf)+1);
assert(str);
strcpy(str,buf);
textline.push(str);
}
//Pop lines from the stack and print them
char *s;
while(0 != (s = (char*)textline.pop()))
{
printf(“%s”,s);
free(s);
}
buf[8] += 8;
return 0;
} //Destructor called here .
////来反汇编:
00410BE0 > 55 push ebp
00410BE1 8BEC mov ebp,esp
00410BE3 6A FF push -1
00410BE5 68 99594100 push lesson3.00415999
00410BEA 64:A1 00000000 mov eax,dword ptr fs:[0]
00410BF0 50 push eax
00410BF1 64:8925 0000000>mov dword ptr fs:[0],esp
00410BF8 81EC BC000000 sub esp,0BC
00410BFE 53 push ebx
00410BFF 56 push esi
00410C00 57 push edi
00410C01 8DBD 38FFFFFF lea edi,dword ptr ss:[ebp-C8]
00410C07 B9 2F000000 mov ecx,2F
00410C0C B8 CCCCCCCC mov eax,CCCCCCCC
00410C11 F3:AB rep stos dword ptr es:[edi]
00410C13 90 nop
00410C14 837D 08 02 cmp dword ptr ss:[ebp+8],2 ; assert (2==argc) 相当于if(..) 弹错!
00410C18 74 1D je short lesson3.00410C37 ; 跳过去继续正常执行
00410C1A 0FBF05 409C4200 movsx eax,word ptr ds:[`main’::`2′::__LINE>
00410C21 83C0 02 add eax,2
00410C24 50 push eax ; assert有三个参数了
00410C25 68 94824200 push lesson3.00428294 ; ASCII “d:\reverse\c++\lesson3\lesson3.cpp”
00410C2A 68 38704200 push lesson3.00427038 ; ASCII “2 == argc”
00410C2F E8 8C2BFFFF call lesson3._assert
00410C34 83C4 0C add esp,0C ; 恢复堆栈
00410C37 68 34704200 push lesson3.00427034
00410C3C 68 88824200 push lesson3.00428288 ; ASCII “c:\test.txt”
00410C41 E8 EA2FFFFF call lesson3.fopen ; fopen
00410C46 83C4 08 add esp,8
00410C49 8945 F0 mov dword ptr ss:[ebp-10],eax ; 打开后文件的指针
00410C4C 837D F0 00 cmp dword ptr ss:[ebp-10],0
00410C50 75 1D jnz short lesson3.00410C6F ; 不为NULL则继续.
00410C52 0FBF15 409C4200 movsx edx,word ptr ds:[`main’::`2′::__LINE>
00410C59 83C2 04 add edx,4
00410C5C 52 push edx
00410C5D 68 94824200 push lesson3.00428294 ; ASCII “d:\reverse\c++\lesson3\lesson3.cpp”
00410C62 68 48824200 push lesson3.00428248 ; ASCII “file”
00410C67 E8 542BFFFF call lesson3._assert
00410C6C 83C4 0C add esp,0C
00410C6F 68 30704200 push lesson3.00427030 ; ASCII “1”,LF
00410C74 E8 2728FFFF call lesson3.printf ; {的外面打印1
00410C79 83C4 04 add esp,4
00410C7C 68 68704200 push lesson3.00427068 ; ASCII “2”,LF
00410C81 E8 1A28FFFF call lesson3.printf ; 进去之后打印2
00410C86 83C4 04 add esp,4
00410C89 8D4D EC lea ecx,dword ptr ss:[ebp-14]
00410C8C E8 7403FFFF call lesson3.00401005 ; 定义类对象时,构造函数执行.
00410C91 68 58704200 push lesson3.00427058 ; ASCII “3”,LF
00410C96 E8 0528FFFF call lesson3.printf ; }的左边打印3
00410C9B 83C4 04 add esp,4
00410C9E 8D4D EC lea ecx,dword ptr ss:[ebp-14]
00410CA1 E8 6903FFFF call lesson3.0040100F ; 出}析构了.
00410CA6 68 2C704200 push lesson3.0042702C ; ASCII “4”,LF
00410CAB E8 F027FFFF call lesson3.printf ; 刚出}的时候来打印4
00410CB0 83C4 04 add esp,4
00410CB3 6A 04 push 4
00410CB5 68 44704200 push lesson3.00427044 ; ASCII “sizeof stack :%d”
00410CBA E8 E127FFFF call lesson3.printf
00410CBF 83C4 08 add esp,8
00410CC2 8A4D 91 mov cl,byte ptr ss:[ebp-6F]
00410CC5 80C1 09 add cl,9
00410CC8 884D 91 mov byte ptr ss:[ebp-6F],cl
00410CCB 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
00410CCE E8 3203FFFF call lesson3.00401005 ; 构造函数
00410CD3 C745 FC 0000000>mov dword ptr ss:[ebp-4],0
00410CDA 8B55 F0 mov edx,dword ptr ss:[ebp-10]
00410CDD 52 push edx ; 文件句柄.
00410CDE 6A 64 push 64 ; size
00410CE0 8D45 88 lea eax,dword ptr ss:[ebp-78] ; 缓冲区
00410CE3 50 push eax
00410CE4 E8 A729FFFF call lesson3.fgets
00410CE9 83C4 0C add esp,0C
00410CEC 85C0 test eax,eax
00410CEE 74 5C je short lesson3.00410D4C ; fgets得到空则玩完
00410CF0 8D4D 88 lea ecx,dword ptr ss:[ebp-78]
00410CF3 51 push ecx
00410CF4 E8 1729FFFF call lesson3.strlen
00410CF9 83C4 04 add esp,4
00410CFC 83C0 01 add eax,1
00410CFF 50 push eax
00410D00 E8 1B08FFFF call lesson3.malloc ; 申请一段内存放buff
00410D05 83C4 04 add esp,4
00410D08 8945 80 mov dword ptr ss:[ebp-80],eax
00410D0B 837D 80 00 cmp dword ptr ss:[ebp-80],0
00410D0F 75 1D jnz short lesson3.00410D2E ; 没申请到下面就玩完
00410D11 0FBF15 409C4200 movsx edx,word ptr ds:[`main’::`2′::__LINE>
00410D18 83C2 11 add edx,11
00410D1B 52 push edx
00410D1C 68 94824200 push lesson3.00428294 ; ASCII “d:\reverse\c++\lesson3\lesson3.cpp”
00410D21 68 20704200 push lesson3.00427020 ; ASCII “str”
00410D26 E8 952AFFFF call lesson3._assert
00410D2B 83C4 0C add esp,0C
00410D2E 8D4D 88 lea ecx,dword ptr ss:[ebp-78]
00410D31 51 push ecx
00410D32 8B55 80 mov edx,dword ptr ss:[ebp-80]
00410D35 52 push edx
00410D36 E8 E527FFFF call lesson3.strcpy ; 放到缓冲区中
00410D3B 83C4 08 add esp,8
00410D3E 8B45 80 mov eax,dword ptr ss:[ebp-80]
00410D41 50 push eax ; 刚刚堆上的字符串
00410D42 8D4D 84 lea ecx,dword ptr ss:[ebp-7C] ; this
00410D45 E8 DE02FFFF call lesson3.00401028 ; 成员函数 stack::push
00410D4A ^ EB 8E jmp short lesson3.00410CDA ; 继续循环.
00410D4C 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
00410D4F E8 CF02FFFF call lesson3.00401023 ; 成员函数.跟了一下发现是pop
00410D54 8985 7CFFFFFF mov dword ptr ss:[ebp-84],eax
00410D5A 83BD 7CFFFFFF 0>cmp dword ptr ss:[ebp-84],0
00410D61 74 25 je short lesson3.00410D88 ; 为0则读完,玩完
00410D63 8B8D 7CFFFFFF mov ecx,dword ptr ss:[ebp-84]
00410D69 51 push ecx
00410D6A 68 1C704200 push lesson3.0042701C ; ASCII “%s”
00410D6F E8 2C27FFFF call lesson3.printf
00410D74 83C4 08 add esp,8
00410D77 8B95 7CFFFFFF mov edx,dword ptr ss:[ebp-84] ; char *s 指针
00410D7D 52 push edx
00410D7E E8 1D12FFFF call lesson3.free ; 释放
00410D83 83C4 04 add esp,4
00410D86 ^ EB C4 jmp short lesson3.00410D4C
00410D88 8A45 90 mov al,byte ptr ss:[ebp-70]
00410D8B 04 08 add al,8
00410D8D 8845 90 mov byte ptr ss:[ebp-70],al
00410D90 C785 78FFFFFF 0>mov dword ptr ss:[ebp-88],0
00410D9A C745 FC FFFFFFF>mov dword ptr ss:[ebp-4],-1
00410DA1 8D4D 84 lea ecx,dword ptr ss:[ebp-7C]
00410DA4 E8 6602FFFF call lesson3.0040100F ; 调用析构函数.
00410DA9 8B85 78FFFFFF mov eax,dword ptr ss:[ebp-88] ; return 0
00410DAF 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00410DB2 64:890D 0000000>mov dword ptr fs:[0],ecx
00410DB9 5F pop edi ; 00241FE4
00410DBA 5E pop esi
00410DBB 5B pop ebx
00410DBC 81C4 C8000000 add esp,0C8
00410DC2 3BEC cmp ebp,esp
00410DC4 E8 6732FFFF call lesson3._chkesp ; 就是看ebp esp了..
00410DC9 8BE5 mov esp,ebp
00410DCB 5D pop ebp
00410DCC C3 retn
////来看看Release版本的:
00401000 /$ 55 push ebp
00401001 |. 8BEC mov ebp,esp
00401003 |. 6A FF push -1
00401005 |. 68 58744000 push lesson3.00407458 ; SE 处理程序安装
0040100A |. 64:A1 0000000>mov eax,dword ptr fs:[0]
00401010 |. 50 push eax
00401011 |. 64:8925 00000>mov dword ptr fs:[0],esp
00401018 |. 83EC 6C sub esp,6C
0040101B |. 53 push ebx
0040101C |. 56 push esi
0040101D |. 90 nop
0040101E |. 68 74904000 push lesson3.00409074
00401023 |. 68 68904000 push lesson3.00409068 ; ASCII “c:\test.txt”
00401028 |. E8 A6030000 call lesson3.004013D3
0040102D |. 68 64904000 push lesson3.00409064 ; ASCII “1”,LF
00401032 |. 8BD8 mov ebx,eax
00401034 |. E8 49030000 call lesson3.00401382
00401039 |. 68 60904000 push lesson3.00409060 ; ASCII “2”,LF
0040103E |. E8 3F030000 call lesson3.00401382
00401043 |. 83C4 10 add esp,10
00401046 |. 8D4D EC lea ecx,[local.5]
00401049 |. E8 22010000 call lesson3.00401170 ; instructor called
0040104E |. 68 5C904000 push lesson3.0040905C ; ASCII “3”,LF
00401053 |. E8 2A030000 call lesson3.00401382
00401058 |. 83C4 04 add esp,4
0040105B |. 8D4D EC lea ecx,[local.5]
0040105E |. E8 7D010000 call lesson3.004011E0 ; destructor called
00401063 |. 68 58904000 push lesson3.00409058 ; ASCII “4”,LF
00401068 |. E8 15030000 call lesson3.00401382
0040106D |. 6A 04 push 4
0040106F |. 68 44904000 push lesson3.00409044 ; ASCII “sizeof stack :%d”
00401074 |. E8 09030000 call lesson3.00401382
00401079 |. 8A4D 91 mov cl,byte ptr ss:[ebp-6F]
0040107C |. 83C4 0C add esp,0C
0040107F |. 80C1 09 add cl,9
00401082 |. 884D 91 mov byte ptr ss:[ebp-6F],cl
00401085 |. 8D4D F0 lea ecx,[local.4]
00401088 |. E8 E3000000 call lesson3.00401170 ; instructor
0040108D |. 53 push ebx
0040108E |. 8D45 88 lea eax,[local.30]
00401091 |. 6A 64 push 64
00401093 |. 50 push eax
00401094 |. C745 FC 00000>mov [local.1],0
0040109B |. E8 8B020000 call lesson3.0040132B ; fgets
004010A0 |. 83C4 0C add esp,0C
004010A3 |. 85C0 test eax,eax
004010A5 |. 74 55 je short lesson3.004010FC
004010A7 |. 57 push edi
004010A8 |> 8D7D 88 /lea edi,[local.30]
004010AB |. 83C9 FF |or ecx,FFFFFFFF
004010AE |. 33C0 |xor eax,eax
004010B0 |. F2:AE |repne scas byte ptr es:[edi]
004010B2 |. F7D1 |not ecx ; 直接把strlen inline进来了, 呵呵
004010B4 |. 51 |push ecx
004010B5 |. E8 BF010000 |call lesson3.00401279 ; malloc
004010BA |. 8BD0 |mov edx,eax
004010BC |. 8D7D 88 |lea edi,[local.30]
004010BF |. 83C9 FF |or ecx,FFFFFFFF
004010C2 |. 33C0 |xor eax,eax
004010C4 |. 83C4 04 |add esp,4
004010C7 |. F2:AE |repne scas byte ptr es:[edi]
004010C9 |. F7D1 |not ecx
004010CB |. 2BF9 |sub edi,ecx
004010CD |. 52 |push edx
004010CE |. 8BC1 |mov eax,ecx
004010D0 |. 8BF7 |mov esi,edi
004010D2 |. 8BFA |mov edi,edx
004010D4 |. C1E9 02 |shr ecx,2
004010D7 |. F3:A5 |rep movs dword ptr es:[edi],dword ptr ds:[esi]
004010D9 |. 8BC8 |mov ecx,eax
004010DB |. 83E1 03 |and ecx,3
004010DE |. F3:A4 |rep movs byte ptr es:[edi],byte ptr ds:[esi] ; strcpy也融入进来了
004010E0 |. 8D4D F0 |lea ecx,[local.4]
004010E3 |. E8 A8000000 |call lesson3.00401190 ; push
004010E8 |. 53 |push ebx
004010E9 |. 8D4D 88 |lea ecx,[local.30]
004010EC |. 6A 64 |push 64
004010EE |. 51 |push ecx
004010EF |. E8 37020000 |call lesson3.0040132B ; fgets
004010F4 |. 83C4 0C |add esp,0C
004010F7 |. 85C0 |test eax,eax
004010F9 |.^ 75 AD \jnz short lesson3.004010A8
004010FB |. 5F pop edi
004010FC |> 8D4D F0 lea ecx,[local.4]
004010FF |. E8 BC000000 call lesson3.004011C0 ; pop
00401104 |. 8BF0 mov esi,eax
00401106 |. 85F6 test esi,esi
00401108 |. 74 22 je short lesson3.0040112C
0040110A |> 56 /push esi
0040110B |. 68 40904000 |push lesson3.00409040 ; ASCII “%s”
00401110 |. E8 6D020000 |call lesson3.00401382 ; 打印
00401115 |. 56 |push esi
00401116 |. E8 F5000000 |call lesson3.00401210 ; free
0040111B |. 83C4 0C |add esp,0C
0040111E |. 8D4D F0 |lea ecx,[local.4]
00401121 |. E8 9A000000 |call lesson3.004011C0 ; 又是pop
00401126 |. 8BF0 |mov esi,eax
00401128 |. 85F6 |test esi,esi
0040112A |.^ 75 DE \jnz short lesson3.0040110A
0040112C |> 8A45 90 mov al,byte ptr ss:[ebp-70]
0040112F |. 8D4D F0 lea ecx,[local.4]
00401132 |. 04 08 add al,8
00401134 |. C745 FC FFFFF>mov [local.1],-1
0040113B |. 8845 90 mov byte ptr ss:[ebp-70],al
0040113E |. E8 9D000000 call lesson3.004011E0 ; 析构
00401143 |. 8B4D F4 mov ecx,[local.3]
00401146 |. 5E pop esi
00401147 |. 33C0 xor eax,eax
00401149 |. 5B pop ebx
0040114A |. 64:890D 00000>mov dword ptr fs:[0],ecx
00401151 |. 8BE5 mov esp,ebp
00401153 |. 5D pop ebp
00401154 \. C3 retn
看来Release版本的变化还真是大, 编译器做了很多的优化, 一定要注意.
还有注意构造函数与析构函数的执行时机, 构造函数实在对象定义的位置执行的, 析构函数是在离开右边的大括号的时候执行的.
没有回复内容