今天做了个小试验,类成员变量的初始化,发现放在参数列表和构造函数体内是一样的...

今天做了个小试验,类成员变量的初始化,发现放在参数列表和构造函数体内是一样的

好久没来了,准备毕业、毕业答辩、毕业、找工作、现在终于稳定下来。突然想到一个问题,随便测试下写写,不要拍砖哈

编译器:VC2005  Release模式,代码不优化
调试器: OllyDBG 1.10
程序如下:

None.gifclass A
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
public:
InBlock.gif A();
InBlock.gif 
~A();
InBlock.gif 
int a;
InBlock.gif 
long b;
ExpandedBlockEnd.gif}
;
None.gif
class B
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
public:
InBlock.gif B();
InBlock.gif 
~B();
InBlock.gif 
int a;
InBlock.gif 
long b;
ExpandedBlockEnd.gif}
;
None.gifA::A() : a(
0)
None.gif ,b(
-1)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedBlockEnd.gif}

None.gifA::~A()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedBlockEnd.gif}

None.gifB::B() 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif a 
= 1;
InBlock.gif b 
= -2;
ExpandedBlockEnd.gif}

None.gifB::~B()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
ExpandedBlockEnd.gif}

None.gifint main()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif __asm
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  push eax   
//加些标记,方便辨认
InBlock.gif  add esp,4
ExpandedSubBlockEnd.gif }
InBlock.gif A a;
InBlock.gif __asm
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  push ebx   
//加些标记,方便辨认
InBlock.gif  push ebx
InBlock.gif  add esp,
8
ExpandedSubBlockEnd.gif }
InBlock.gif B b;
InBlock.gif 
InBlock.gif 
return 0;
ExpandedBlockEnd.gif}


对应的汇编及分析如下:
对应的汇编及分析如下:
 

None.gif对应的汇编及分析如下:
None.gif 
None.gif
//类A的构造函数
None.gif00401000  /$  55            push    ebp           //将当前栈基址压栈保存
None.gif00401001  |.  8BEC          mov     ebp, esp      //将当前栈指针作为栈基址
None.gif00401003  |.  51            push    ecx        //this指针压栈
None.gif00401004  |.  894D FC       mov     dword ptr [ebp-4], ecx     //保存this指针
None.gif00401007  |.  8B45 FC       mov     eax, dword ptr [ebp-4]     //this指针放入eax
None.gif0040100A  |.  C700 00000000 mov     dword ptr [eax], 0         //this指针指向的地址存入0,也就是变量a,对应语句*(int*)this=0;
None.gif00401010  |.  8B4D FC       mov     ecx, dword ptr [ebp-4]     //this指针放入ecx(多余的一步)
None.gif00401013  |.  C741 04 FFFFF>mov     dword ptr [ecx+4], -1      //this指针指向的地址存入-1,也就是变量b,对应语句*(int*)(this+4)=-1;
None.gif0040101A  |.  8B45 FC       mov     eax, dword ptr [ebp-4]     //返回值放入eax
None.gif0040101D  |.  8BE5          mov     esp, ebp                   //还原先前的esp、ebp
None.gif0040101F  |.  5D            pop     ebp
None.gif
00401020  \.  C3            retn
None.gif
//中间代码省略
None.gif
//类B的构造函数,和a的一模一样
None.gif00401030  /$  55            push    ebp
None.gif
00401031  |.  8BEC          mov     ebp, esp
None.gif
00401033  |.  51            push    ecx
None.gif
00401034  |.  894D FC       mov     dword ptr [ebp-4], ecx
None.gif
00401037  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
None.gif0040103A  
|.  C700 01000000 mov     dword ptr [eax], 1
None.gif00401040  |.  8B4D FC       mov     ecx, dword ptr [ebp-4]
None.gif
00401043  |.  C741 04 FEFFF>mov     dword ptr [ecx+4], -2
None.gif0040104A  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
None.gif0040104D  
|.  8BE5          mov     esp, ebp
None.gif0040104F  
|.  5D            pop     ebp
None.gif
00401050  \.  C3            retn
None.gif
//中间代码省略
None.gif
//2个类公用一个析构函数
None.gif00401060  /$  55            push    ebp
None.gif
00401061  |.  8BEC          mov     ebp, esp
None.gif
00401063  |.  51            push    ecx
None.gif
00401064  |.  894D FC       mov     dword ptr [ebp-4], ecx
None.gif
00401067  |.  8BE5          mov     esp, ebp
None.gif
00401069  |.  5D            pop     ebp
None.gif0040106A  \.  C3            retn
None.gif
//中间代码省略
None.gif
//main()函数
None.gif00401070  /$  55            push    ebp
None.gif
00401071  |.  8BEC          mov     ebp, esp
None.gif
00401073  |.  83EC 14       sub     esp, 14   //给变量分配20字节空间
None.gif00401076  |.  50            push    eax      //刚才的代码标记
None.gif00401077  |.  83C4 04       add     esp, 4   //刚才的代码标记
None.gif0040107A  |.  8D4D F8       lea     ecx, dword ptr [ebp-8]      //thiscall调用约定,this指针通过ecx传递
None.gif0040107D  |.  E8 7EFFFFFF   call    00401000        //调用A构造函数
None.gif00401082  |.  53            push    ebx     //刚才的代码标记
None.gif00401083  |.  53            push    ebx    //刚才的代码标记
None.gif00401084  |.  83C4 08       add     esp, 8   //刚才的代码标记
None.gif00401087  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]     //thiscall调用约定,this指针通过ecx传递    
None.gif0040108A  |.  E8 A1FFFFFF   call    00401030   //调用B构造函数
None.gif0040108F  |.  C745 EC 00000>mov     dword ptr [ebp-14], 0      //函数返回值预先存储好
None.gif00401096  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
None.gif
00401099  |.  E8 C2FFFFFF   call    00401060                 //调用B析构函数
None.gif0040109E  |.  8D4D F8       lea     ecx, dword ptr [ebp-8]
None.gif004010A1  
|.  E8 BAFFFFFF   call    00401060                 //调用A析构函数
None.gif004010A6  |.  8B45 EC       mov     eax, dword ptr [ebp-14]   //返回值最后放入eax
None.gif004010A9  |.  8BE5          mov     esp, ebp
None.gif004010AB  
|.  5D            pop     ebp
None.gif004010AC  \.  C3            retn


由此可见,成员变量放在初始化列表和构造函数体内,汇编代码是一样的,也就是不管放在那里,是没有差别的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值