⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_c++类机制的实现细节.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 2 页
字号:
          <TD align=middle height=5></TD>
          <TD align=middle width=500></TD></TR>
        <TR>
          <TD align=middle bgColor=#003399 height=10><FONT 
            color=#ffffff>标题</FONT></TD>
          <TD><B>&nbsp;&nbsp;&nbsp;&nbsp;C++类机制的实现细节</B>&nbsp;&nbsp;&nbsp;&nbsp;nightsuns(原作) 
          </TD></TR>
        <TR>
          <TD align=middle height=5></TD>
          <TD align=middle width=500></TD></TR>
        <TR>
          <TD align=middle bgColor=#003399><FONT color=#ffffff>关键字</FONT></TD>
          <TD width=500>&nbsp;&nbsp;&nbsp;&nbsp;类机制 实现细节</TD></TR>
        <TR>
          <TD align=middle height=5></TD>
          <TD align=middle width=500></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
      <TABLE border=0 width=600>
        <TBODY>
        <TR>
          <TD align=left><BR>
            <P><SPAN id=yuyuzi>为了搞清楚VC中类的实现专门写了一个最简单的类,用来观察它的实现过程,代码如下:<BR>// 
            test.cpp : Defines the entry point for the console 
            application.<BR>//<BR><BR>#include "stdafx.h"<BR>#include 
            "CTest.h"<BR><BR>int main(int argc, char* argv[])<BR>{<BR>CTest 
            aTest;<BR>aTest.a(1,2);<BR>return 0;<BR>}<BR><BR>// CTest.h: 
            interface for the CTest 
            class.<BR>//<BR>//////////////////////////////////////////////////////////////////////<BR><BR>#if 
            !defined(AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_)<BR>#define 
            AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_<BR><BR>#if 
            _MSC_VER &gt; 1000<BR>#pragma once<BR>#endif // _MSC_VER &gt; 
            1000<BR><BR>class CTest <BR>{<BR>public:<BR>CTest();<BR>virtual 
            ~CTest();<BR><BR>public:<BR>void b();<BR>void a(int one,int 
            two);<BR>};<BR><BR>#endif // 
            !defined(AFX_CTEST_H__2CCCDCFC_6C3A_48BC_9CD0_E7A8E63431D9__INCLUDED_)<BR><BR><BR>// 
            CTest.cpp: implementation of the CTest 
            class.<BR>//<BR>//////////////////////////////////////////////////////////////////////<BR><BR>#include 
            "stdafx.h"<BR>#include 
            "CTest.h"<BR><BR>//////////////////////////////////////////////////////////////////////<BR>// 
            Construction/Destruction<BR>//////////////////////////////////////////////////////////////////////<BR><BR>CTest::CTest()<BR>{<BR><BR>}<BR><BR>CTest::~CTest()<BR>{<BR><BR>}<BR><BR>void 
            CTest::b()<BR>{<BR>printf("b is be called by a");<BR>}<BR><BR>void 
            CTest::a(int one,int two)<BR>{<BR>printf("call 
            b");<BR>b();<BR>}<BR><BR><BR><BR><BR>下面是相应的反汇编代码:<BR>--- 
            D:\myown\test\test.cpp -----------------------------------------------------------------------------------------------<BR>1:  // 
            test.cpp : Defines the entry point for the console 
            application.<BR>2:  //<BR>3:<BR>4:  #include 
            "stdafx.h"<BR>5:  #include "CTest.h"<BR>6:<BR>7:  int main(int argc, 
            char* argv[])<BR>8:  {<BR>00401050  push    ebp<BR>00401051  mov     
            ebp,esp<BR>00401053  push    0FFh<BR>00401055  push    offset 
            __ehhandler$_main (00410c89)<BR>0040105A  mov     
            eax,fs:[00000000]<BR>00401060  push    eax<BR>00401061  mov     
            dword ptr fs:[0],esp<BR>00401068  sub     esp,48h<BR>0040106B  
            push    ebx<BR>0040106C  push    esi<BR>0040106D  
            push    edi<BR>0040106E  lea     edi,[ebp-54h]<BR>00401071  mov     
            ecx,12h<BR>00401076  mov     eax,0CCCCCCCCh<BR>0040107B  rep 
            stos  dword ptr [edi]<BR><BR>9:    CTest aTest;<BR>0040107D  lea     
            ecx,[ebp-10h] //这是用来保存aTest的this指针,因为是局部变量所以是保存在[ebp-10h]中<BR>00401080  
            call    @ILT+30(CTest::CTest) 
            (00401023) //调用aTest的构造函数,由编译器自动产生的CALL<BR>00401085  mov     dword 
            ptr [ebp-4],0<BR><BR>10:    aTest.a(1,2);<BR>0040108C  
            push    2<BR>0040108E  push    1<BR>00401090  lea     
            ecx,[ebp-10h] //把aTest的this指针用ecx进行传递<BR>00401093  
            call    @ILT+5(CTest::a) (0040100a) <BR>11:    return 
            0;<BR>00401098  mov     dword ptr [ebp-14h],0<BR>0040109F  mov     
            dword ptr [ebp-4],0FFFFFFFFh<BR>004010A6  lea     
            ecx,[ebp-10h] //同样是this指针<BR>004010A9  
            call    @ILT+25(CTest::~CTest) 
            (0040101e) //aTest的生存周期到了,自动调用析构函数,同样是由编译器分析之后自加上去<BR>004010AE  
            mov     eax,dword ptr [ebp-14h]<BR>12:  }<BR>004010B1  mov     
            ecx,dword ptr [ebp-0Ch]<BR>004010B4  mov     dword ptr 
            fs:[0],ecx<BR>004010BB  pop     edi<BR>004010BC  pop     
            esi<BR>004010BD  pop     ebx<BR>004010BE  add     
            esp,54h<BR>004010C1  cmp     ebp,esp<BR>004010C3  call    __chkesp 
            (00401670)<BR>004010C8  mov     esp,ebp<BR>004010CA  pop     
            ebp<BR>004010CB  
            ret<BR><BR>下面再来分析一下VC中对函数的调用:<BR>可以看到上面有对三个函数的调用分别为:<BR>00401080  
            call    @ILT+30(CTest::CTest) (00401023)<BR>00401093  
            call    @ILT+5(CTest::a) (0040100a)<BR>004010A9  
            call    @ILT+25(CTest::~CTest) 
            (0040101e)<BR><BR>可以看到他们都跳到了以@ILT为基的一个地址去了,那么跳过去之后可以看到:<BR>@ILT+0(??_GCTest@@UAEPAXI@Z):<BR>00401005  
            jmp     CTest::`scalar deleting destructor' 
            (00401130)<BR>@ILT+5(?a@CTest@@QAEXHH@Z):<BR>0040100A  jmp     
            CTest::a (00401230)<BR>@ILT+10(_main):<BR>0040100F  jmp     main 
            (00401050)<BR>@ILT+15(?b@CTest@@QAEXXZ):<BR>00401014  jmp     
            CTest::b (004011e0)<BR>@ILT+20(??_GCTest@@UAEPAXI@Z):<BR>00401019  
            jmp     CTest::`scalar deleting destructor' 
            (00401130)<BR>@ILT+25(??1CTest@@UAE@XZ):<BR>0040101E  jmp     
            CTest::~CTest (004011a0)<BR>@ILT+30(??0CTest@@QAE@XZ):<BR>00401023  
            jmp     CTest::CTest 
            (004010f0)<BR><BR>这个@ILT其实就是一个静态的表,它记录了一些函数的入口然后跳过去,每个跳转jmp占一个字节,然后就是一个四字节的内存地址,所以加起为五个字节,这样就实现了类的机制。<BR><BR>下面再来分析一下,类的成员函数调用另一成员函数的情况:<BR><BR>27:  
            void CTest::a(int one,int two)<BR>28:  {<BR>00401230  
            push    ebp<BR>00401231  mov     ebp,esp<BR>00401233  sub     
            esp,44h<BR>00401236  push    ebx<BR>00401237  
            push    esi<BR>00401238  push    edi<BR>00401239  
            push    ecx<BR>0040123A  lea     edi,[ebp-44h]<BR>0040123D  mov     
            ecx,11h<BR>00401242  mov     eax,0CCCCCCCCh<BR>00401247  rep 
            stos  dword ptr [edi]<BR>00401249  pop     ecx<BR>0040124A  mov     
            dword ptr [ebp-4],ecx<BR>29:    printf("call b");<BR>0040124D  
            push    offset string "call b" (00422038)<BR>00401252  
            call    printf (00401830)<BR>00401257  add     esp,4<BR>30:    
            b();<BR>0040125A  mov     ecx,dword ptr [ebp-4] 
            //不要想这里的[ebp-4]肯定是this指针,<BR>0040125D  call    @ILT+15(CTest::b) 
            (00401014) // 又是@ILT静态表格<BR>31:  }<BR>00401262  pop     
            edi<BR>00401263  pop     esi<BR>00401264  pop     ebx<BR>00401265  
            add     esp,44h<BR>00401268  cmp     ebp,esp<BR>0040126A  
            call    __chkesp (00401670)<BR>0040126F  mov     
            esp,ebp<BR>00401271  pop     ebp<BR>00401272  ret     
            8   //由于是STDCALLR所以栈是由程序自己来平衡的<BR></SPAN></P><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center bgColor=#006699 border=0 cellPadding=0 cellSpacing=0 
width=770>
  <TBODY>
  <TR bgColor=#006699>
    <TD align=middle bgColor=#006699 id=white><FONT 
    color=#ffffff>对该文的评论</FONT></TD>
    <TD align=middle>
      <SCRIPT src="CSDN_文档中心_C++类机制的实现细节.files/readnum.htm"></SCRIPT>
    </TD></TR></TBODY></TABLE><BR>
<DIV align=center>
<TABLE align=center bgColor=#cccccc border=0 cellPadding=2 cellSpacing=1 
width=770>
  <TBODY>
  <TR>
    <TH bgColor=#006699 id=white><FONT 
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<SCRIPT language=javascript>
	<!--
	function isEmpty(s)
	{  
		return ((s == null) || (s.length == 0))
	}
	function fubmitok()
	{
		if (isEmpty(document.add_critique.Critique_Content.value))
		{
			alert('评论不能为空!!!!')   ;
			return false;
		}
		document.add_critique.submit();
	}
	//-->
	</SCRIPT>

<DIV align=center>
<TABLE border=0 width=770>
  <TBODY>
  <TR>
    <TD>
      <FORM action=Critique_Sql.asp method=post name=add_critique><INPUT 
      name=Critique_State type=hidden value=add> &nbsp;&nbsp;评论人:xyj0323 
      &nbsp;&nbsp;评论:<BR>&nbsp;&nbsp;<TEXTAREA cols=104 name=Critique_Content rows=8></TEXTAREA><BR>&nbsp;&nbsp;<INPUT name=ubmit onclick=javascript:fubmitok(); type=button value=发表评论> 
      <INPUT name=Topic_id type=hidden value=27050> <INPUT name=From type=hidden 
      value=/Develop/Build_Article.asp?id=27050> 
</FORM></TD></TR></TBODY></TABLE></DIV><BR>
<HR noShade SIZE=1 width=770>

<TABLE border=0 cellPadding=0 cellSpacing=0 width=500>
  <TBODY>
  <TR align=middle>
    <TD height=10 vAlign=bottom><A 
      href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A 
      href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A 
      href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A 
      href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A 
      href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A 
      href="http://www.csdn.net/english">English</A> </TD>
    <TD align=middle rowSpan=3><A 
      href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG 
      border=0 height=48 src="CSDN_文档中心_C++类机制的实现细节.files/biaoshi.gif" 
      width=40></A></TD></TR>
  <TR align=middle>
    <TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
  <TR align=middle>
    <TD vAlign=top><FONT face=Verdana>Copyright &copy; CSDN.net, Inc. All rights 
      reserved</FONT></TD></TR>
  <TR>
    <TD height=15></TD>
    <TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--内容结束//--><!--结束//--></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -